Harden-Windows-Security.ps1
<#PSScriptInfo
.VERSION 2023.1.29 .GUID d435a293-c9ee-4217-8dc1-4ad2318a5770 .AUTHOR HotCakeX .COMPANYNAME SpyNetGirl .COPYRIGHT 2023 .TAGS Windows Hardening Security Bitlocker Defender Firewall Edge Protection .LICENSEURI .PROJECTURI https://github.com/HotCakeX/Harden-Windows-Security .ICONURI https://raw.githubusercontent.com/HotCakeX/Harden-Windows-Security/main/ICONURI.png .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES ## Version 2022.12.8: Improved the script ## Version 2022.12.9: Configured LSASS process to run as a protected process with UEFI Lock ## Version 2022.12.9.1: Added new icon for the script ## Version 2022.12.10: Enabled ECH (Encrypted Client Hello of TLS) feature for Edge browser ## Version 2022.12.25: Entirely changed and organized the script's style to be easier to read and find commands ## Version 2022.12.26: Further improved the script with explanatory comments and improved the Optional Windows Features section ## Version 2022.12.26.1: Significantly improved Bitlocker script block, logic and style ## Version 2022.12.26.2: Optimized the script by performing registry modifications using a function and saved 600 lines of code ## Version 2023.1: The script now allows you to run each hardening category separately and added 2 more categories, 1) certificates and 2) Country IP Blocking ## Version 2023.1.1: added a checking process to the country IP blocking category so that if the list is empty, no rule will be created. ## Version 2023.1.1.1: Changed description of the PowerShell Gallery's page ## Version 2023.1.10: Removed old unnecessary outdated commands, removed most of the links and all descriptions from the script file, USE GITHUB PAGE FOR THE REFERENCE AND PROPER EXPLANATION. ## Version 2023.1.12: changed Firewall LOLBin blocking section to be faster with Parallel operations and added Secured-core PC compliancy ## Version 2023.1.12.1: Fixed description text in PowerShell Gallery ## Version 2023.1.13: Fixed the Country IP blocking list and made it fully compliant with https://www.state.gov/state-sponsors-of-terrorism/ ## Version 2023.1.13.1: Removed the ECH related commands, they weren't official methods, removed Russia in country IP blocking since it wasn't mentioned in https://www.state.gov/state-sponsors-of-terrorism/ . changed Windows time sync interval from every 7 days to every 4 days (previous script value was 2). ## Version 2023.1.13.2: made Firewall processing section faster by defining a ThrottleLimit based on CPU's logical cores ## Version 2023.1.16: Bitlocker category now encrypts all drives instead of just OS drive. Certificate checking category now handles situations when WebDav can't be used. ## Version 2023.1.17: fixed text spacing and colors to improve readability, removed LOLBins blocking as it's no longer necessary to do so. the security features in place make LOLBins blocking unnecessary and redundant and blocking those programs in Firewall can have unknown/unwated behavior. ## Version 2023.1.22: Added a notice at the beginning of the script to remind the user to read GitHub readme page. added Smart App Control to the Windows Security (Defender) section. script asks for confirmation before turning on Smart App Control. ## Version 2023.1.23: Changed the registry modification function with a more advanced one. changed code style to reduce function call and use hash tables. Improved the overall design and style of the script. Changed 'ConsentPromptBehaviorAdmin' from UAC category to a #TopSecurity tagged command. see this GitHub issue for more info. https://github.com/HotCakeX/Harden-Windows-Security/issues/2#issuecomment-1400115303 . removed PowerShell Core requirement. ## Version 2023.1.24: enforce encryption type on removable and fixed drive types to full disk encryption instead of only used disk encryption ## Version 2023.1.25: The script now applies the official Microsoft Security Baselines and on top of that applies as many of the script settings as possible using Group Policy, the rest of the settings that aren't possible to be applied using Group Policy continue to be applied using registry and PowerShell Cmdlets. ## Version 2023.1.26: completely optimized the script, changed it to be multilingual-friendly and people with non-English language packs installed or with non-English keyboards, will have an easy time using the script. Thanks to the community feedback on GitHub! ## Version 2023.1.28: Bitlocker DMA protection enables only when Kernel DMA protection is unavailable, as suggested by Microsoft, and this happens using Group Policies instead of registry. Improved verbosity when importing and installing policies. ## Version 2023.1.29: Improved Security Baselines categories. added error handling when no Internet connection is available to download them. #> <# .SYNOPSIS Harden Windows 11 safely, securely using Official Supported methods with proper explanation .DESCRIPTION ⭕ You need to read the GitHub's readme page before running this script: https://github.com/HotCakeX/Harden-Windows-Security 💠 Features of this Hardening script: ✅ Always up-to-date and works with latest build of Windows (Currently Windows 11 - compatible and rigorously tested on stable and Insider Dev builds) ✅ Doesn't break anything ✅ Doesn't remove or disable Windows functionalities against Microsoft's recommendation ✅ The Readme page on GitHub is used as the reference for all of the security measures applied by this script and Group Policies. the order in which they appear there is the same as the one in the script file. ✅ When a hardening command is no longer necessary because it's applied by default by Microsoft on new builds of Windows, it will also be removed from this script in order to prevent any problems and because it won't be necessary anymore. ✅ The script can be run infinite number of times, it's made in a way that it won't make any duplicate changes at all. ✅ The script asks for confirmation, in the PowerShell console, before running each hardening category, so you can selectively run (or don't run) each of them. ✅ Running this script makes your PC compliant with Secured-core PC specifications (providing that you use a modern hardware that supports the latest Windows security features). ✅ Running this script makes your system compliant with the official Microsoft Security Baselines 🛑 Warning: Windows by default is secure and safe, this script does not imply nor claim otherwise. just like anything, you have to use it wisely and don't compromise yourself with reckless behavior and bad user configuration; Nothing is foolproof. this script only uses the tools and features that have already been implemented by Microsoft in Windows OS to fine-tune it towards the highest security and locked-down state, using well-documented, supported, often recommended and official methods. continue reading for comprehensive info. 💠 Hardening Categories from top to bottom: (🔺Detailed info about each of them at my Github🔻) ⏹ Commands that require Administrator Privileges ✅Microsoft Security Baselines ✅Security Baselines X ✅ Windows Security aka Defender ✅ Attack surface reduction rules ✅ Bitlocker Settings ✅ TLS Security ✅ Lock Screen ✅ UAC (User Account Control) ✅ Device Guard ✅ Windows Firewall ✅ Optional Windows Features ✅ Windows Networking ✅ Miscellaneous Configurations ✅ Certificate Checking Commands ✅ Country IP Blocking ⏹ Commands that don't require Administrator Privileges ✅ Non-Admin Commands that only affect the current user and do not make machine-wide changes. 💎 Note: if there are multiple Windows user accounts in your computer, it's recommended to run this script in each of them, without administrator privileges, because Non-admin commands only apply to the current user and are not machine wide. 💎 Note: The script asks for confirmation, in the PowerShell console, before running each hardening category, so you can selectively run (or don't run) each of them. 💎 Note: There are 4 items tagged with #TopSecurity that can break functionalities or cause difficulties so this script does NOT enable them by default. press Control + F and search for #TopSecurity in the GitHub Readme page to find those security measures and how to enable them if you want. 🏴 if you have any questions, requests, suggestions etc. about this script, please open a new discussion in Github: 🟡 https://github.com/HotCakeX/Harden-Windows-Security/discussions .EXAMPLE type: "Set-ExecutionPolicy Bypass -Scope Process" without quotes, in an Elevated PowerShell, to allow running this script for the current session. .NOTES Check out GitHub page for security recommendations: https://github.com/HotCakeX/Harden-Windows-Security #> $infomsg = "`r`n" + "#############################################################################################################`r`n" + "### Make Sure you've completely read what's written in the GitHub repository, before running this script ###`r`n" + "#############################################################################################################`r`n" Write-Host $infomsg -ForegroundColor Cyan $infomsg = "`r`n" + "###########################################################################################`r`n" + "### Link to the GitHub Repository: https://github.com/HotCakeX/Harden-Windows-Security ###`r`n" + "###########################################################################################`r`n" Write-Host $infomsg -ForegroundColor Green # check if user's OS is Windows Home edition if (((Get-WmiObject Win32_OperatingSystem).OperatingSystemSKU) -eq "101") { Write-host "Windows Home edition detected, exiting..." -ForegroundColor Red break } #region Functions # Questions function function Select-Option { param( [parameter(Mandatory = $true, Position = 0)][string]$Message, [parameter(Mandatory = $true, Position = 1)][string[]]$Options ) $Selected = $null while ($null -eq $Selected) { Write-Host $Message -ForegroundColor Magenta for ($i = 0; $i -lt $Options.Length; $i++) { Write-Host "$($i+1): $($Options[$i])" } $SelectedIndex = Read-Host "Select an option" if ($SelectedIndex -gt 0 -and $SelectedIndex -le $Options.Length) { $Selected = $Options[$SelectedIndex - 1] } else { Write-Host "Invalid Option." -ForegroundColor Yellow } } return $Selected } # Registry modification function function ModifyRegistry { param ( [Parameter(Mandatory = $false)][HashTable]$HashTable, [Parameter(Mandatory = $false)][String]$RegPath, [Parameter(Mandatory = $false)][String]$RegName, [Parameter(Mandatory = $false)][String]$RegValue ) function processit { param([hashtable]$hash) If (-NOT (Test-Path $hash.RegPath)) { New-Item -Path $hash.RegPath -Force | Out-Null } New-ItemProperty -Path $hash.RegPath -Name $hash.RegName -Value $hash.RegValue -PropertyType DWORD -Force [pscustomobject]@{ Path = $hash.RegPath Name = $hash.RegName Value = $hash.RegValue } } if ($HashTable) { if ($HashTable.ContainsKey('RegPath')) { processit -hash $HashTable } else { foreach ($item in $HashTable.GetEnumerator()) { if ($item.Value -is [hashtable]) { if ($item.Value.ContainsKey('RegPath') -and $item.Value.ContainsKey('RegValue')) { $hash = $item.Value if (-not $hash.ContainsKey('RegName')) { $hash.RegName = $item.Key } processit -hash $hash } else { Write-Warning "Invalid hashtable format - missing RegPath and/or RegValue key" } } else { Write-Warning "Item does not contain a hashtable" } } } } else { processit @{RegPath = $RegPath; RegName = $RegName; RegValue = $RegValue } } } # https://devblogs.microsoft.com/scripting/use-function-to-determine-elevation-of-powershell-console/ # Function to test if current session has administrator privileges Function Test-IsAdmin { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal $identity $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) } #endregion functions if (-NOT (Test-IsAdmin)) { write-host "Skipping commands that require Administrator privileges" -ForegroundColor Magenta } else { #region Security-Baselines # ========================================================================================================================= # ================================================Security Baselines======================================================= # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "`nApply Microsoft Security Baseline + Hardening Script's Baseline?") { "Yes" { # Hiding invoke-webrequest progress because it creates lingering visual effect on PowerShell console for some reason # https://github.com/PowerShell/PowerShell/issues/14348 # https://stackoverflow.com/questions/18770723/hide-progress-of-invoke-webrequest # Create an in-memory module so $ScriptBlock doesn't run in new scope $null = New-Module { function Invoke-WithoutProgress { [CmdletBinding()] param ( [Parameter(Mandatory)] [scriptblock] $ScriptBlock ) # Save current progress preference and hide the progress $prevProgressPreference = $global:ProgressPreference $global:ProgressPreference = 'SilentlyContinue' try { # Run the script block in the scope of the caller of this module function . $ScriptBlock } finally { # Restore the original behavior $global:ProgressPreference = $prevProgressPreference } } } # create our working directory New-Item -ItemType Directory -Path ".\HardeningXStuff\" -Force # change location to the new directory Push-Location ".\HardeningXStuff\" Write-Host "Downloading the required files, Please wait..." -ForegroundColor Yellow Invoke-WithoutProgress { try { # download Microsoft Security Baselines directly from their servers Invoke-WebRequest -Uri "https://download.microsoft.com/download/8/5/C/85C25433-A1B0-4FFA-9429-7E023E7DA8D8/Windows%2011%20version%2022H2%20Security%20Baseline.zip" -OutFile ".\Windows1122H2SecurityBaseline.zip" -ErrorAction Stop # Download LGPO program from Microsoft servers Invoke-WebRequest -Uri "https://download.microsoft.com/download/8/5/C/85C25433-A1B0-4FFA-9429-7E023E7DA8D8/LGPO.zip" -OutFile ".\LGPO.zip" -ErrorAction Stop # Download the Group Policies of Windows Hardening script from GitHub Invoke-WebRequest -Uri "https://github.com/HotCakeX/Harden-Windows-Security/raw/main/GroupPolicy/Security-Baselines-X.zip" -OutFile ".\Security-Baselines-X.zip" -ErrorAction Stop } catch { Write-Host "The required files couldn't be downloaded, skipping this category..." -ForegroundColor Red break } } # unzip Microsoft Security Baselines file Expand-Archive -Path .\Windows1122H2SecurityBaseline.zip -DestinationPath .\ -Force # unzip the LGPO file Expand-Archive -Path .\LGPO.zip -DestinationPath .\ -Force # unzip the Security-Baselines-X file which contains Windows Hardening script Group Policy Objects expand-Archive -Path .\Security-Baselines-X.zip -DestinationPath .\Security-Baselines-X\ -Force # Copy LGPO.exe from its folder to Microsoft Security Baseline folder in order to get it ready to be used by PowerShell script Copy-Item -Path ".\LGPO_30\LGPO.exe" -Destination ".\Windows-11-v22H2-Security-Baseline\Scripts\Tools" # Change directory to the Security Baselines folder Push-Location ".\Windows-11-v22H2-Security-Baseline\Scripts\" # Run the official PowerShell script included in the Microsoft Security Baseline file we downloaded from Microsoft servers .\Baseline-LocalInstall.ps1 -Win11NonDomainJoined # Change current working directory back to where we were Pop-Location # Change current working directory to the LGPO's folder Push-Location ".\LGPO_30" # Import settings from Security Baselines X Registry Policy file into Computer (Machine) Configuration. Write-Host "Importing Security Baselines X Machine wide policies" -ForegroundColor Green .\LGPO.exe /m "..\Security-Baselines-X\GPOX\DomainSysvol\GPO\Machine\registry.pol" # Apply the Security Baselines X security template into Computer (Machine) Configuration Write-Host "Importing Security Baselines X Security Policies" -ForegroundColor Green .\LGPO.exe /s "..\Security-Baselines-X\GPOX\DomainSysvol\GPO\Machine\microsoft\windows nt\SecEdit\GptTmpl.inf" # This PowerShell script can be used to find out if the DMA Protection is ON \ OFF. # The Script will show this by emitting True \ False for On \ Off respectively. # bootDMAProtection check - checks for Kernel DMA Protection status in System information or msinfo32 $bootDMAProtectionCheck = @" namespace SystemInfo { using System; using System.Runtime.InteropServices; public static class NativeMethods { internal enum SYSTEM_DMA_GUARD_POLICY_INFORMATION : int { /// </summary> SystemDmaGuardPolicyInformation = 202 } [DllImport("ntdll.dll")] internal static extern Int32 NtQuerySystemInformation( SYSTEM_DMA_GUARD_POLICY_INFORMATION SystemDmaGuardPolicyInformation, IntPtr SystemInformation, Int32 SystemInformationLength, out Int32 ReturnLength); public static byte BootDmaCheck() { Int32 result; Int32 SystemInformationLength = 1; IntPtr SystemInformation = Marshal.AllocHGlobal(SystemInformationLength); Int32 ReturnLength; result = NativeMethods.NtQuerySystemInformation( NativeMethods.SYSTEM_DMA_GUARD_POLICY_INFORMATION.SystemDmaGuardPolicyInformation, SystemInformation, SystemInformationLength, out ReturnLength); if (result == 0) { byte info = Marshal.ReadByte(SystemInformation, 0); return info; } return 0; } } } "@ Add-Type -TypeDefinition $bootDMAProtectionCheck # returns true or false depending on whether Kernel DMA Protection is on or off $bootDMAProtection = ([SystemInfo.NativeMethods]::BootDmaCheck()) -ne 0 # Enables or disables DMA protection from Bitlocker Countermeasures based on the status of Kernel DMA protection. if ($bootDMAProtection) { Write-Host "Kernel DMA protection is enabled on the system, disabling Bitlocker DMA protection." -ForegroundColor Blue .\LGPO.exe /m "..\Security-Baselines-X\Bitlocker DMA\Bitlocker DMA Countermeasure OFF\Registry.pol" } else { Write-Host "Kernel DMA protection is unavailable on the system, enabling Bitlocker DMA protection." -ForegroundColor Blue .\LGPO.exe /m "..\Security-Baselines-X\Bitlocker DMA\Bitlocker DMA Countermeasure ON\Registry.pol" } # Change the current working directory back to where we started Pop-Location;Pop-Location # delete our working directory remove-item -Path ".\HardeningXStuff" -Recurse -Force } "No" { break } "Exit" { exit } } # ========================================================================================================================= # ============================================End of Security Baselines==================================================== # ========================================================================================================================= #endregion Security-Baselines #region Windows-Security-Defender # ========================================================================================================================= # ==========================================Windows Security aka Defender================================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Windows Security (Defender) category ?") { "Yes" { # Optimizing Network Protection Performance of Windows Defender - this was off by default on Windows 11 insider build 25247 Set-MpPreference -AllowSwitchToAsyncInspection $True switch (Select-Option -Options "Yes", "No", "Exit" -Message "Turn on Smart App Control ?") { "Yes" { # Turn on Smart App Control ModifyRegistry -RegPath 'HKLM:\SYSTEM\CurrentControlSet\Control\CI\Policy' -RegName 'VerifiedAndReputablePolicyState' -RegValue '1' } "No" { break } "Exit" { exit } } } "No" { break } "Exit" { exit } } # ========================================================================================================================= # =========================================End of Windows Security aka Defender============================================ # ========================================================================================================================= #endregion Windows-Security-Defender #region Bitlocker-Settings # ========================================================================================================================= # ==========================================Bitlocker Settings============================================================= # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Bitlocker category ?") { "Yes" { # set-up Bitlocker encryption for OS Drive with TPMandPIN and recovery password keyprotectors and Verify its implementation # https://learn.microsoft.com/en-us/powershell/module/bitlocker/remove-bitlockerkeyprotector?view=windowsserver2022-ps # Once it's done, it saves the recovery password in a text file in the encrypted drive # Make sure to keep it in a safe place, e.g. in OneDrive's Personal Vault which requires authentication to access. <# https://stackoverflow.com/questions/48809012/compare-two-credentials-in-powershell Safely compares two SecureString objects without decrypting them. Outputs $true if they are equal, or $false otherwise. #> function Compare-SecureString { param( [Security.SecureString] $secureString1, [Security.SecureString] $secureString2 ) try { $bstr1 = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString1) $bstr2 = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString2) $length1 = [Runtime.InteropServices.Marshal]::ReadInt32($bstr1, -4) $length2 = [Runtime.InteropServices.Marshal]::ReadInt32($bstr2, -4) if ( $length1 -ne $length2 ) { return $false } for ( $i = 0; $i -lt $length1; ++$i ) { $b1 = [Runtime.InteropServices.Marshal]::ReadByte($bstr1, $i) $b2 = [Runtime.InteropServices.Marshal]::ReadByte($bstr2, $i) if ( $b1 -ne $b2 ) { return $false } } return $true } finally { if ( $bstr1 -ne [IntPtr]::Zero ) { [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr1) } if ( $bstr2 -ne [IntPtr]::Zero ) { [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr2) } } } # check, make sure there is no CD/DVD drives in the system, because Bitlocker throws an error when there is $CDDVDCheck = (Get-WMIObject -Class Win32_CDROMDrive -Property *).MediaLoaded if ($CDDVDCheck) { Write-Warning "Remove any CD/DVD drives from the system and run the Bitlocker category after that" break } # check, make sure Bitlocker isn't in the middle of decryption/encryption operation (on System Drive) if ((Get-BitLockerVolume -MountPoint $env:SystemDrive).EncryptionPercentage -ne "100" -and (Get-BitLockerVolume -MountPoint $env:SystemDrive).EncryptionPercentage -ne "0") { $kawai = (Get-BitLockerVolume -MountPoint $env:SystemDrive).EncryptionPercentage Write-Host "Please wait for Bitlocker operation to finish encrypting or decrypting the disk" -ForegroundColor Magenta Write-Host "drive $env:SystemDrive encryption is currently at $kawai" -ForegroundColor Magenta } else { # check if Bitlocker is enabled for the system drive if ((Get-BitLockerVolume -MountPoint $env:SystemDrive).ProtectionStatus -eq "on") { $KeyProtectors = (Get-BitLockerVolume -MountPoint $env:SystemDrive).KeyProtector.keyprotectortype # check if TPM, PIN and recovery password are being used with Bitlocker which are the safest settings if ($KeyProtectors -contains 'Tpmpin' -and $KeyProtectors -contains 'recoveryPassword') { Write-Host "Bitlocker is fully and securely enabled for OS drive" -ForegroundColor Green } else { # check if Bitlocker is using TPM and PIN but not recovery password as key protector if ($KeyProtectors -contains 'Tpmpin' -and $KeyProtectors -notcontains 'recoveryPassword') { Add-BitLockerKeyProtector -MountPoint $env:SystemDrive -RecoveryPasswordProtector *> "$env:SystemDrive\Drive $($env:SystemDrive.remove(1)) recovery password.txt" Write-Host "TPM and Startup Pin are available but the recovery password is missing, adding it now... `nthe recovery password will be saved in a Text file in $env:SystemDrive\Drive $($env:SystemDrive.remove(1)) recovery password.txt" -ForegroundColor yellow Write-Host "Make sure to keep it in a safe place, e.g. in OneDrive's Personal Vault which requires authentication to access." -ForegroundColor Blue } # check if Bitlocker is using recovery password but not TPM and PIN if ($KeyProtectors -notcontains 'Tpmpin' -and $KeyProtectors -contains 'recoveryPassword') { Write-Host "TPM and Start up PIN key protectors are missing but recovery password key protector is in place, `nadding TPM and Start up PIN key protectors now..." -ForegroundColor Magenta do { $pin1 = $(write-host "Enter a Pin for Bitlocker startup (at least 6 digits)" -ForegroundColor Magenta; Read-Host -AsSecureString) $pin2 = $(write-host "Confirm your Bitlocker Startup Pin (at least 6 digits)" -ForegroundColor Magenta; Read-Host -AsSecureString) $theyMatch = Compare-SecureString $pin1 $pin2 if ( $theyMatch -and $pin1.Length -gt 5 -and $pin2.Length -gt 5 ) { $pin = $pin1 } else { Write-Host "the PINs you entered didn't match, try again" -ForegroundColor red } } until ( $theyMatch -and $pin1.Length -gt 5 -and $pin2.Length -gt 5 ) try { Add-BitLockerKeyProtector -MountPoint $env:SystemDrive -TpmAndPinProtector -Pin $pin -ErrorAction Stop Write-Host "PINs matched, enabling TPM and startup PIN now" -ForegroundColor DarkMagenta } catch { Write-Host "These errors occured, run Bitlocker category again after meeting the requirements" -ForegroundColor Red $Error break } } } } else { Write-Host "Bitlocker is Not enabled for the System Drive Drive, activating now..." -ForegroundColor yellow do { $pin1 = $(write-host "Enter a Pin for Bitlocker startup (at least 6 digits)" -ForegroundColor Magenta; Read-Host -AsSecureString) $pin2 = $(write-host "Confirm your Bitlocker Startup Pin (at least 6 digits)" -ForegroundColor Magenta; Read-Host -AsSecureString) $theyMatch = Compare-SecureString $pin1 $pin2 if ( $theyMatch -and $pin1.Length -gt 5 -and $pin2.Length -gt 5 ) { $pin = $pin1 } else { Write-Host "the Pins you entered didn't match, try again" -ForegroundColor red } } until ( $theyMatch -and $pin1.Length -gt 5 -and $pin2.Length -gt 5 ) try { enable-bitlocker -MountPoint $env:SystemDrive -EncryptionMethod XtsAes256 -pin $pin -TpmAndPinProtector -SkipHardwareTest -ErrorAction Stop } catch { Write-Host "These errors occured, run Bitlocker category again after meeting the requirements" -ForegroundColor Red $Error break } Add-BitLockerKeyProtector -MountPoint $env:SystemDrive -RecoveryPasswordProtector *> "$env:SystemDrive\Drive $($env:SystemDrive.remove(1)) recovery password.txt" Resume-BitLocker -MountPoint $env:SystemDrive Write-Host "the recovery password will be saved in a Text file in $env:SystemDrive\Drive $($env:SystemDrive.remove(1)) recovery password.txt `nMake sure to keep it in a safe place, e.g. in OneDrive's Personal Vault which requires authentication to access." -ForegroundColor Blue Write-Host "Bitlocker is now fully and securely enabled for OS drive" -ForegroundColor Green } } # Enable Bitlocker for all the other drives # check if there is any other drive besides OS drive $nonOSVolumes = Get-BitLockerVolume | Where-Object { $_.volumeType -ne "OperatingSystem" } if ($nonOSVolumes) { $nonOSVolumes | ForEach-Object { $MountPoint = $_.MountPoint if ((Get-BitLockerVolume -MountPoint $MountPoint).EncryptionPercentage -ne "100" -and (Get-BitLockerVolume -MountPoint $MountPoint).EncryptionPercentage -ne "0") { $kawai = (Get-BitLockerVolume -MountPoint $MountPoint).EncryptionPercentage Write-Host "Please wait for Bitlocker operation to finish encrypting or decrypting drive $MountPoint" -ForegroundColor Magenta Write-Host "drive $MountPoint encryption is currently at $kawai" -ForegroundColor Magenta } else { if ((Get-BitLockerVolume -MountPoint $MountPoint).ProtectionStatus -eq "on") { $KeyProtectors = (Get-BitLockerVolume -MountPoint $MountPoint).KeyProtector.keyprotectortype if ($KeyProtectors -contains 'RecoveryPassword') { Write-Host "Bitlocker is fully and securely enabled for drive $MountPoint" -ForegroundColor Green } else { Add-BitLockerKeyProtector -MountPoint $MountPoint -RecoveryPasswordProtector *> "$MountPoint\Drive $($MountPoint.Remove(1)) recovery password.txt"; Enable-BitLockerAutoUnlock -MountPoint $MountPoint Write-Host "Bitlocker Recovery Password has been added for drive $MountPoint . it will be saved in a Text file in $($MountPoint)\Drive $($MountPoint.Remove(1)) recovery password.txt `nMake sure to keep it in a safe place, e.g. in OneDrive's Personal Vault which requires authentication to access." -ForegroundColor Blue } } else { Enable-BitLocker -MountPoint $MountPoint -RecoveryPasswordProtector *> "$MountPoint\Drive $($MountPoint.Remove(1)) recovery password.txt"; Enable-BitLockerAutoUnlock -MountPoint $MountPoint Write-Host "Bitlocker has started encrypting drive $MountPoint . recovery password will be saved in a Text file in $($MountPoint)\Drive $($MountPoint.Remove(1)) recovery password.txt `nMake sure to keep it in a safe place, e.g. in OneDrive's Personal Vault which requires authentication to access." -ForegroundColor Blue } } } } # end of if statement for detecting whether there is any non-OS drives } "No" { break } "Exit" { exit } } # ========================================================================================================================= # ==========================================End of Bitlocker Settings====================================================== # ========================================================================================================================= #endregion Bitlocker-Settings #region TLS-Security # ========================================================================================================================= # ==============================================TLS Security=============================================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run TLS Security category ?") { "Yes" { $TLS = [ordered]@{ # Disable TLS v1 Key1 = @{ RegName = 'DisabledByDefault' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client' RegValue = '1' } Key2 = @{ RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client' RegValue = '0' } key3 = @{ RegName = 'DisabledByDefault' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server' RegValue = '1' } Key4 = @{ RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server' RegValue = '0' } # Disable TLS v1.1 Key5 = @{ RegName = 'DisabledByDefault' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client' RegValue = '1' } Key6 = @{ RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client' RegValue = '0' } Key7 = @{ RegName = 'DisabledByDefault' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server' RegValue = '1' } Key8 = @{ RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server' RegValue = '0' } } # Disable TLS v1 and v1.1 ModifyRegistry -HashTable $TLS # Enable TLS_CHACHA20_POLY1305_SHA256 Cipher Suite which is available but not enabled by default in Windows 11 Enable-TlsCipherSuite -Name "TLS_CHACHA20_POLY1305_SHA256" -Position 0 # disabling weak cipher suites try { # Disable NULL Cipher Suites - 1 Disable-TlsCipherSuite TLS_RSA_WITH_NULL_SHA256 # Disable NULL Cipher Suites - 2 Disable-TlsCipherSuite TLS_RSA_WITH_NULL_SHA # Disable NULL Cipher Suites - 3 Disable-TlsCipherSuite TLS_PSK_WITH_NULL_SHA384 # Disable NULL Cipher Suites - 4 Disable-TlsCipherSuite TLS_PSK_WITH_NULL_SHA256 Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_GCM_SHA384" Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_GCM_SHA256" Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA256" Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_CBC_SHA256" Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA" Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_CBC_SHA" Disable-TlsCipherSuite -Name "TLS_PSK_WITH_AES_256_GCM_SHA384" Disable-TlsCipherSuite -Name "TLS_PSK_WITH_AES_128_GCM_SHA256" Disable-TlsCipherSuite -Name "TLS_PSK_WITH_AES_256_CBC_SHA384" Disable-TlsCipherSuite -Name "TLS_PSK_WITH_AES_128_CBC_SHA256" } catch { Write-Host "All weak TLS Cipher Suites have been disabled" -ForegroundColor Magenta } # Enabling Diffie–Hellman based key exchange algorithms # TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 # must be already available by default according to Microsoft Docs but it isn't, on Windows 11 insider dev build 25272 # https://learn.microsoft.com/en-us/windows/win32/secauthn/tls-cipher-suites-in-windows-11 Enable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" # TLS_DHE_RSA_WITH_AES_128_CBC_SHA # Not enabled by default on Windows 11 according to the Microsoft Docs above Enable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" # TLS_DHE_RSA_WITH_AES_256_CBC_SHA # Not enabled by default on Windows 11 according to the Microsoft Docs above Enable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" # Disabling weak and unsecure ciphers @( # creating these registry keys that have forward slashes in them 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56', # DES 56-bit 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 40/128', # RC2 40-bit 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 56/128', # RC2 56-bit 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 128/128', # RC2 128-bit 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128', # RC4 40-bit 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128', # RC4 56-bit 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128', # RC4 64-bit 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128', # RC4 128-bit 'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\Triple DES 168' # 3DES 168-bit (Triple DES 168) ) | ForEach-Object { ([Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $env:COMPUTERNAME)).CreateSubKey($_) } $WeakCiphers = [ordered]@{ key1 = @{ #NULL RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\NULL\' RegValue = '0' } key2 = @{ # DES 56-bit RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56' RegValue = '0' } key3 = @{ # RC2 40-bit RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 40/128' RegValue = '0' } key4 = @{ # RC2 56-bit RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 56/128' RegValue = '0' } key5 = @{ # RC2 128-bit RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 128/128' RegValue = '0' } key6 = @{ # RC4 40-bit RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128' RegValue = '0' } key7 = @{ # RC4 56-bit RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128' RegValue = '0' } key8 = @{ # RC4 64-bit RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128' RegValue = '0' } key9 = @{ # RC4 128-bit RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128' RegValue = '0' } key10 = @{ # 3DES 168-bit (Triple DES 168) RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\Triple DES 168' RegValue = '0' } key11 = @{ # Disable MD5 Hashing Algorithm RegName = 'Enabled' RegPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes\MD5' RegValue = '0' } } # Disabling Weak Ciphers and MD5 Hashing Algorithm ModifyRegistry -HashTable $WeakCiphers } "No" { break } "Exit" { exit } } # ========================================================================================================================= # ==========================================End of TLS Security============================================================ # ========================================================================================================================= #endregion TLS-Security #region Windows-Firewall # ========================================================================================================================= # ====================================================Windows Firewall===================================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Windows Firewall category ?") { "Yes" { # Disables Multicast DNS (mDNS) UDP-in Firewall Rules for all 3 Firewall profiles - disables only 3 rules get-NetFirewallRule | Where-Object { $_.RuleGroup -eq "@%SystemRoot%\system32\firewallapi.dll,-37302" -and $_.Direction -eq "inbound" } | ForEach-Object { Disable-NetFirewallRule -DisplayName $_.DisplayName } } "No" { break } "Exit" { exit } } # ========================================================================================================================= # =================================================End of Windows Firewall================================================= # ========================================================================================================================= #endregion Windows-Firewall #region Optional-Windows-Features # ========================================================================================================================= # =================================================Optional Windows Features=============================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Optional Windows Features category ?") { "Yes" { # since PowerShell Core (only if installed from Microsoft Store) has problem with these commands, making sure the built-in PowerShell handles them # There are Github issues for it already: https://github.com/PowerShell/PowerShell/issues/13866 # Disable PowerShell v2 (needs 2 commands) PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2).state -eq 'enabled'){disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2 -norestart}else{Write-Host 'MicrosoftWindowsPowerShellV2 is already disabled' -ForegroundColor Darkgreen}" PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root).state -eq 'enabled'){disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root -norestart}else{Write-Host 'MicrosoftWindowsPowerShellV2Root is already disabled' -ForegroundColor Darkgreen}" # Disable Work Folders client PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName WorkFolders-Client).state -eq 'enabled'){disable-WindowsOptionalFeature -Online -FeatureName WorkFolders-Client -norestart}else{Write-Host 'WorkFolders-Client is already disabled' -ForegroundColor Darkgreen}" # Disable Internet Printing Client PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName Printing-Foundation-Features).state -eq 'enabled'){disable-WindowsOptionalFeature -Online -FeatureName Printing-Foundation-Features -norestart}else{Write-Host 'Printing-Foundation-Features is already disabled' -ForegroundColor Darkgreen}" # Disable Windows Media Player (legacy) PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName WindowsMediaPlayer).state -eq 'enabled'){disable-WindowsOptionalFeature -Online -FeatureName WindowsMediaPlayer -norestart}else{Write-Host 'WindowsMediaPlayer is already disabled' -ForegroundColor Darkgreen}" # Enable Windows Defender Application Guard PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName Windows-Defender-ApplicationGuard).state -eq 'disabled'){enable-WindowsOptionalFeature -Online -FeatureName Windows-Defender-ApplicationGuard -norestart}else{Write-Host 'Windows-Defender-ApplicationGuard is already enabled' -ForegroundColor Darkgreen}" # Enable Windows Sandbox PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName Containers-DisposableClientVM).state -eq 'disabled'){enable-WindowsOptionalFeature -Online -FeatureName Containers-DisposableClientVM -All -norestart}else{Write-Host 'Containers-DisposableClientVM (Windows Sandbox) is already enabled' -ForegroundColor Darkgreen}" # Enable Hyper-V PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V).state -eq 'disabled'){enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All -norestart}else{Write-Host 'Microsoft-Hyper-V is already enabled' -ForegroundColor Darkgreen}" # Enable Virtual Machine Platform PowerShell.exe "if((get-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform).state -eq 'disabled'){enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -norestart}else{Write-Host 'VirtualMachinePlatform is already enabled' -ForegroundColor Darkgreen}" } "No" { break } "Exit" { exit } } # ========================================================================================================================= # ==============================================End of Optional Windows Features=========================================== # ========================================================================================================================= #endregion Optional-Windows-Features #region Windows-Networking # ========================================================================================================================= # ====================================================Windows Networking=================================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Windows Networking category ?") { "Yes" { # disable LMHOSTS lookup protocol on all network adapters ModifyRegistry -RegPath 'HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters' -RegName 'EnableLMHOSTS' -RegValue '0' # Set the Network Location of all connections to Public Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Public } "No" { break } "Exit" { exit } } # ========================================================================================================================= # =================================================End of Windows Networking=============================================== # ========================================================================================================================= #endregion Windows-Networking #region Miscellaneous-Configurations # ========================================================================================================================= # ==============================================Miscellaneous Configurations=============================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Miscellaneous Configurations category ?") { "Yes" { # Set Hibnernate mode to full powercfg /h /type full # Enable Mandatory ASLR set-processmitigation -System -Enable ForceRelocateImages # You can add Mandatory ASLR override for a Trusted App using the command below or in the Program Settings section of Exploit Protection in Windows Defender app. # Set-ProcessMitigation -Name "C:\TrustedApp.exe" -Disable ForceRelocateImages # Turn on Enhanced mode search for Windows indexer ModifyRegistry -RegPath 'HKLM:\SOFTWARE\Microsoft\Windows Search' -RegName 'EnableFindMyFiles' -RegValue '1' # Enable SMB Encryption - using force to confirm the action Set-SmbServerConfiguration -EncryptData $true -force # Set Microsoft Edge to update over Metered connections ModifyRegistry -RegPath 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\ClientStateMedium\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}' -RegName 'allowautoupdatesmetered' -RegValue '1' # Enable notify me when a restart is required to finish updating ModifyRegistry -RegPath 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' -RegName 'RestartNotificationsAllowed2' -RegValue '1' # Allow all Windows users to use Hyper-V and Windows Sandbox by adding all Windows users to the "Hyper-V Administrators" security group Get-LocalUser | Where-Object { $_.enabled -EQ "True" } | Select-Object "Name" | ForEach-Object { Add-LocalGroupMember -Group "Hyper-V Administrators" -Member $_.Name -ErrorAction SilentlyContinue } # Change Windows time sync interval from every 7 days to every 4 days (= every 345600 seconds) ModifyRegistry -RegPath 'HKLM:\SYSTEM\ControlSet001\Services\W32Time\TimeProviders\NtpClient' -RegName 'SpecialPollInterval' -RegValue '345600' } "No" { break } "Exit" { exit } } # ========================================================================================================================= # ============================================End of Miscellaneous Configurations========================================== # ========================================================================================================================= #endregion Miscellaneous-Configurations #region Certificate-Checking-Commands # ========================================================================================================================= # ====================================================Certificate Checking Commands======================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Certificate Checking category ?") { "Yes" { # List valid certificates not rooted to the Microsoft Certificate Trust List in the User store switch (Select-Option -Options "Yes", "No", "Exit" -Message "List valid certificates not rooted to the Microsoft Certificate Trust List in the User store ?") { "Yes" { try { \\live.sysinternals.com\tools\sigcheck64.exe -tuv -accepteula -nobanner } catch { Invoke-WebRequest -Uri "https://live.sysinternals.com/sigcheck64.exe" -OutFile "sigcheck64.exe" .\sigcheck64.exe -tuv -accepteula -nobanner Remove-Item .\sigcheck64.exe } } "No" { break } "Exit" { exit } } # List valid certificates not rooted to the Microsoft Certificate Trust List in the Machine store switch (Select-Option -Options "Yes", "No", "Exit" -Message "List valid certificates not rooted to the Microsoft Certificate Trust List in the Machine store ?") { "Yes" { try { \\live.sysinternals.com\tools\sigcheck64.exe -tv -accepteula -nobanner } catch { Invoke-WebRequest -Uri "https://live.sysinternals.com/sigcheck64.exe" -OutFile "sigcheck64.exe" .\sigcheck64.exe -tv -accepteula -nobanner Remove-Item .\sigcheck64.exe } } "No" { break } "Exit" { exit } } } "No" { break } "Exit" { exit } } # ========================================================================================================================= # ====================================================End of Certificate Checking Commands================================= # ========================================================================================================================= #endregion Certificate-Checking-Commands #region Country-IP-Blocking # ========================================================================================================================= # ====================================================Country IP Blocking================================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Country IP Blocking category ?") { "Yes" { # -RemoteAddress in New-NetFirewallRule accepts array according to Microsoft Docs, # so we use "[string[]]$IPList = $IPList -split '\r?\n' -ne ''" to convert the IP lists, which is a single multiline string, into an array function BlockCountryIP { param ($IPList , $CountryName) # checks if the rule is present and if it is, deletes them to get new up-to-date IP ranges from the sources if (Get-NetFirewallRule -DisplayName "$CountryName IP range blocking" -PolicyStore localhost 2> $null) { Remove-NetFirewallRule -DisplayName "$CountryName IP range blocking" -PolicyStore localhost } # converts the list which is in string into array [string[]]$IPList = $IPList -split '\r?\n' -ne '' # makes sure the list isn't empty if ($IPList.count -eq 0) { Write-Host "The IP list was empty, skipping $CountryName" -ForegroundColor Yellow ; break } New-NetFirewallRule -DisplayName "$CountryName IP range blocking" -Direction Inbound -Action Block -LocalAddress Any -RemoteAddress $IPList -Description "$CountryName IP range blocking" -Profile Any -InterfaceType Any -Group "Hardening-Script-CountryIP-Blocking" -EdgeTraversalPolicy Block -PolicyStore localhost New-NetFirewallRule -DisplayName "$CountryName IP range blocking" -Direction Outbound -Action Block -LocalAddress Any -RemoteAddress $IPList -Description "$CountryName IP range blocking" -Profile Any -InterfaceType Any -Group "Hardening-Script-CountryIP-Blocking" -EdgeTraversalPolicy Block -PolicyStore localhost } # Iran switch (Select-Option -Options "Yes", "No", "Exit" -Message "Block the entire range of IPv4 and IPv6 belonging to Iran?") { "Yes" { $IranIPv4 = Invoke-RestMethod -Uri "https://www.ipdeny.com/ipblocks/data/aggregated/ir-aggregated.zone" $IranIPv6 = Invoke-RestMethod -Uri "https://www.ipdeny.com/ipv6/ipaddresses/blocks/ir.zone" $IranIPRange = $IranIPv4 + $IranIPv6 BlockCountryIP -IPList $IranIPRange -CountryName "Iran" } "No" { break } "Exit" { exit } } # Cuba switch (Select-Option -Options "Yes", "No", "Exit" -Message "Block the entire range of IPv4 and IPv6 belonging to Cuba?") { "Yes" { $CubaIPv4 = Invoke-RestMethod -Uri "https://www.ipdeny.com/ipblocks/data/aggregated/cu-aggregated.zone" $CubaIPv6 = Invoke-RestMethod -Uri "https://www.ipdeny.com/ipv6/ipaddresses/blocks/cu.zone" $CubaIPRange = $CubaIPv4 + $CubaIPv6 BlockCountryIP -IPList $CubaIPRange -CountryName "Cuba" } "No" { break } "Exit" { exit } } # North Korea switch (Select-Option -Options "Yes", "No", "Exit" -Message "Block the entire range of IPv4 and IPv6 belonging to North Korea?") { "Yes" { $NorthKoreaIPv4 = Invoke-RestMethod -Uri "https://www.ipdeny.com/ipblocks/data/aggregated/kp-aggregated.zone" $NorthKoreaIPv6 = Invoke-RestMethod -Uri "https://www.ipdeny.com/ipv6/ipaddresses/blocks/kn.zone" $NorthKoreaIPRange = $NorthKoreaIPv4 + $NorthKoreaIPv6 BlockCountryIP -IPList $NorthKoreaIPRange -CountryName "North Korea" } "No" { break } "Exit" { exit } } # Syria switch (Select-Option -Options "Yes", "No", "Exit" -Message "Block the entire range of IPv4 and IPv6 belonging to Syria?") { "Yes" { $SyriaIPv4 = Invoke-RestMethod -Uri "https://www.ipdeny.com/ipblocks/data/aggregated/sy-aggregated.zone" $SyriaIPv6 = Invoke-RestMethod -Uri "https://www.ipdeny.com/ipv6/ipaddresses/blocks/sy.zone" $SyriaIPRange = $SyriaIPv4 + $SyriaIPv6 BlockCountryIP -IPList $SyriaIPRange -CountryName "Syria" } "No" { break } "Exit" { exit } } # how to query the number of IPs in each rule # (Get-NetFirewallRule -DisplayName "Cuba IP range blocking" | Get-NetFirewallAddressFilter).RemoteAddress.count } "No" { break } "Exit" { exit } } # ========================================================================================================================= # ====================================================End of Country IP Blocking=========================================== # ========================================================================================================================= #endregion Country-IP-Blocking } # End of Admin test function #region Non-Admin-Commands # ========================================================================================================================= # ====================================================Non-Admin Commands=================================================== # ========================================================================================================================= switch (Select-Option -Options "Yes", "No", "Exit" -Message "Run Non-Admin category ?") { "Yes" { # Show known file extensions in File explorer ModifyRegistry -RegPath 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -RegName 'HideFileExt' -RegValue '0' # Show hidden files, folders and drives (toggles the control panel folder options item) ModifyRegistry -RegPath 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -RegName 'Hidden' -RegValue '1' # Disable websites accessing local language list ModifyRegistry -RegPath 'HKCU:\Control Panel\International\User Profile' -RegName 'HttpAcceptLanguageOptOut' -RegValue '1' # turn off safe search in Windows search. from Windows settings > privacy and security > search permissions > safe search ModifyRegistry -RegPath 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings' -RegName 'SafeSearchMode' -RegValue '0' # prevent showing notifications in Lock screen - this is the same as toggling the button in Windows settings > system > notifications > show notifications in the lock screen ModifyRegistry -RegPath 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings' -RegName 'NOC_GLOBAL_SETTING_ALLOW_TOASTS_ABOVE_LOCK' -RegValue '0' # prevent showing notifications in Lock screen, 2nd reg key - this is the same as toggling the button in Windows settings > system > notifications > show notifications in the lock screen ModifyRegistry -RegPath 'HKCU:\Software\Microsoft\Windows\CurrentVersion\PushNotifications' -RegName 'LockScreenToastEnabled' -RegValue '0' # Enable Clipboard History for the current user ModifyRegistry -RegPath 'HKCU:\Software\Microsoft\Clipboard' -RegName 'EnableClipboardHistory' -RegValue '1' # 2 commands to enable sync of Clipboard history in Windows between devices ModifyRegistry -RegPath 'HKCU:\Software\Microsoft\Clipboard' -RegName 'CloudClipboardAutomaticUpload' -RegValue '1' # last one, to enable Clipboard sync ModifyRegistry -RegPath 'HKCU:\Software\Microsoft\Clipboard' -RegName 'EnableCloudClipboard' -RegValue '1' # creates Custom Views for Event Viewer in "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\" # Event Viewer custom views are saved in "C:\ProgramData\Microsoft\Event Viewer\Views". files in there can be backed up and restored on new Windows installations. # attack surface reduction rules events $path_0 = "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_0.xml" if (-NOT (Test-Path $path_0)) { New-Item -Path $path_0 -ItemType File -Force $View_0 = @" <ViewerConfig><QueryConfig><QueryParams><UserQuery /></QueryParams><QueryNode><Name LanguageNeutralValue="attack surface reduction rule events">attack surface reduction rule events</Name><QueryList><Query Id="0" Path="Microsoft-Windows-Windows Defender/Operational"><Select Path="Microsoft-Windows-Windows Defender/Operational">*[System[(EventID=1121 or EventID=1122 or EventID=5007)]]</Select><Select Path="Microsoft-Windows-Windows Defender/WHC">*[System[(EventID=1121 or EventID=1122 or EventID=5007)]]</Select></Query></QueryList></QueryNode></QueryConfig><ResultsConfig><Columns><Column Name="Level" Type="System.String" Path="Event/System/Level" Visible="">111</Column><Column Name="Keywords" Type="System.String" Path="Event/System/Keywords">70</Column><Column Name="Date and Time" Type="System.DateTime" Path="Event/System/TimeCreated/@SystemTime" Visible="">190</Column><Column Name="Source" Type="System.String" Path="Event/System/Provider/@Name" Visible="">215</Column><Column Name="Event ID" Type="System.UInt32" Path="Event/System/EventID" Visible="">124</Column><Column Name="Task Category" Type="System.String" Path="Event/System/Task" Visible="">74</Column><Column Name="User" Type="System.String" Path="Event/System/Security/@UserID">50</Column><Column Name="Operational Code" Type="System.String" Path="Event/System/Opcode">110</Column><Column Name="Log" Type="System.String" Path="Event/System/Channel">80</Column><Column Name="Computer" Type="System.String" Path="Event/System/Computer">170</Column><Column Name="Process ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessID">70</Column><Column Name="Thread ID" Type="System.UInt32" Path="Event/System/Execution/@ThreadID">70</Column><Column Name="Processor ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessorID">90</Column><Column Name="Session ID" Type="System.UInt32" Path="Event/System/Execution/@SessionID">70</Column><Column Name="Kernel Time" Type="System.UInt32" Path="Event/System/Execution/@KernelTime">80</Column><Column Name="User Time" Type="System.UInt32" Path="Event/System/Execution/@UserTime">70</Column><Column Name="Processor Time" Type="System.UInt32" Path="Event/System/Execution/@ProcessorTime">100</Column><Column Name="Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@ActivityID">85</Column><Column Name="Relative Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@RelatedActivityID">140</Column><Column Name="Event Source Name" Type="System.String" Path="Event/System/Provider/@EventSourceName">140</Column></Columns></ResultsConfig></ViewerConfig> "@ Add-Content -Path "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_0.xml" -Value $View_0 } # controlled folder access events $path_1 = "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_1.xml" if (-NOT (Test-Path $path_1)) { New-Item -Path $path_1 -ItemType File $View_1 = @" <ViewerConfig><QueryConfig><QueryParams><UserQuery /></QueryParams><QueryNode><Name LanguageNeutralValue="controlled folder access events">controlled folder access events</Name><QueryList><Query Id="0" Path="Microsoft-Windows-Windows Defender/Operational"><Select Path="Microsoft-Windows-Windows Defender/Operational">*[System[(EventID=1123 or EventID=1124 or EventID=5007)]]</Select><Select Path="Microsoft-Windows-Windows Defender/WHC">*[System[(EventID=1123 or EventID=1124 or EventID=5007)]]</Select></Query></QueryList></QueryNode></QueryConfig></ViewerConfig> "@ Add-Content -Path "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_1.xml" -Value $View_1 } # exploit protection events $path_2 = "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_2.xml" if (-NOT (Test-Path $path_2)) { New-Item -Path $path_2 -ItemType File $View_2 = @" <ViewerConfig><QueryConfig><QueryParams><UserQuery /></QueryParams><QueryNode><Name LanguageNeutralValue="exploit protection events">exploit protection events</Name><SortConfig Asc="0"><Column Name="Date and Time" Type="System.DateTime" Path="Event/System/TimeCreated/@SystemTime" Visible="">275</Column></SortConfig><QueryList><Query Id="0" Path="Microsoft-Windows-Security-Mitigations/KernelMode"><Select Path="Microsoft-Windows-Security-Mitigations/KernelMode">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Win32k/Concurrency">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Win32k/Contention">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Win32k/Messages">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Win32k/Operational">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Win32k/Power">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Win32k/Render">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Win32k/Tracing">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Win32k/UIPI">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select><Select Path="Microsoft-Windows-Security-Mitigations/UserMode">*[System[Provider[@Name='Microsoft-Windows-Security-Mitigations' or @Name='Microsoft-Windows-WER-Diag' or @Name='Microsoft-Windows-Win32k' or @Name='Win32k'] and ( (EventID >= 1 and EventID <= 24) or EventID=5 or EventID=260)]]</Select></Query></QueryList></QueryNode></QueryConfig><ResultsConfig><Columns><Column Name="Level" Type="System.String" Path="Event/System/Level" Visible="">225</Column><Column Name="Keywords" Type="System.String" Path="Event/System/Keywords">70</Column><Column Name="Date and Time" Type="System.DateTime" Path="Event/System/TimeCreated/@SystemTime" Visible="">275</Column><Column Name="Source" Type="System.String" Path="Event/System/Provider/@Name" Visible="">242</Column><Column Name="Event ID" Type="System.UInt32" Path="Event/System/EventID" Visible="">185</Column><Column Name="Task Category" Type="System.String" Path="Event/System/Task" Visible="">188</Column><Column Name="User" Type="System.String" Path="Event/System/Security/@UserID">50</Column><Column Name="Operational Code" Type="System.String" Path="Event/System/Opcode">110</Column><Column Name="Log" Type="System.String" Path="Event/System/Channel">80</Column><Column Name="Computer" Type="System.String" Path="Event/System/Computer">170</Column><Column Name="Process ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessID">70</Column><Column Name="Thread ID" Type="System.UInt32" Path="Event/System/Execution/@ThreadID">70</Column><Column Name="Processor ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessorID">90</Column><Column Name="Session ID" Type="System.UInt32" Path="Event/System/Execution/@SessionID">70</Column><Column Name="Kernel Time" Type="System.UInt32" Path="Event/System/Execution/@KernelTime">80</Column><Column Name="User Time" Type="System.UInt32" Path="Event/System/Execution/@UserTime">70</Column><Column Name="Processor Time" Type="System.UInt32" Path="Event/System/Execution/@ProcessorTime">100</Column><Column Name="Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@ActivityID">85</Column><Column Name="Relative Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@RelatedActivityID">140</Column><Column Name="Event Source Name" Type="System.String" Path="Event/System/Provider/@EventSourceName">140</Column></Columns></ResultsConfig></ViewerConfig> "@ Add-Content -Path "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_2.xml" -Value $View_2 } # network protection events $path_3 = "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_3.xml" if (-NOT (Test-Path $path_3)) { New-Item -Path $path_3 -ItemType File $View_3 = @" <ViewerConfig><QueryConfig><QueryParams><UserQuery /></QueryParams><QueryNode><Name LanguageNeutralValue="network protection events">network protection events</Name><QueryList><Query Id="0" Path="Microsoft-Windows-Windows Defender/Operational"><Select Path="Microsoft-Windows-Windows Defender/Operational">*[System[(EventID=1125 or EventID=1126 or EventID=5007)]]</Select><Select Path="Microsoft-Windows-Windows Defender/WHC">*[System[(EventID=1125 or EventID=1126 or EventID=5007)]]</Select></Query></QueryList></QueryNode></QueryConfig><ResultsConfig><Columns><Column Name="Level" Type="System.String" Path="Event/System/Level" Visible="">225</Column><Column Name="Keywords" Type="System.String" Path="Event/System/Keywords">70</Column><Column Name="Date and Time" Type="System.DateTime" Path="Event/System/TimeCreated/@SystemTime" Visible="">275</Column><Column Name="Source" Type="System.String" Path="Event/System/Provider/@Name" Visible="">242</Column><Column Name="Event ID" Type="System.UInt32" Path="Event/System/EventID" Visible="">185</Column><Column Name="Task Category" Type="System.String" Path="Event/System/Task" Visible="">188</Column><Column Name="User" Type="System.String" Path="Event/System/Security/@UserID">50</Column><Column Name="Operational Code" Type="System.String" Path="Event/System/Opcode">110</Column><Column Name="Log" Type="System.String" Path="Event/System/Channel">80</Column><Column Name="Computer" Type="System.String" Path="Event/System/Computer">170</Column><Column Name="Process ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessID">70</Column><Column Name="Thread ID" Type="System.UInt32" Path="Event/System/Execution/@ThreadID">70</Column><Column Name="Processor ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessorID">90</Column><Column Name="Session ID" Type="System.UInt32" Path="Event/System/Execution/@SessionID">70</Column><Column Name="Kernel Time" Type="System.UInt32" Path="Event/System/Execution/@KernelTime">80</Column><Column Name="User Time" Type="System.UInt32" Path="Event/System/Execution/@UserTime">70</Column><Column Name="Processor Time" Type="System.UInt32" Path="Event/System/Execution/@ProcessorTime">100</Column><Column Name="Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@ActivityID">85</Column><Column Name="Relative Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@RelatedActivityID">140</Column><Column Name="Event Source Name" Type="System.String" Path="Event/System/Provider/@EventSourceName">140</Column></Columns></ResultsConfig></ViewerConfig> "@ Add-Content -Path "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_3.xml" -Value $View_3 } # MSI and Scripts for WDAC Auditing events $path_4 = "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_4.xml" if (-NOT (Test-Path $path_4)) { New-Item -Path $path_4 -ItemType File $View_4 = @" <ViewerConfig><QueryConfig><QueryParams><Simple><Channel>Microsoft-Windows-AppLocker/MSI and Script</Channel><RelativeTimeInfo>0</RelativeTimeInfo><BySource>False</BySource></Simple></QueryParams><QueryNode><Name LanguageNeutralValue="MSI and Scripts for WDAC Auditing">MSI and Scripts for WDAC Auditing</Name><QueryList><Query Id="0" Path="Microsoft-Windows-AppLocker/MSI and Script"><Select Path="Microsoft-Windows-AppLocker/MSI and Script">*</Select></Query></QueryList></QueryNode></QueryConfig><ResultsConfig><Columns><Column Name="Level" Type="System.String" Path="Event/System/Level" Visible="">225</Column><Column Name="Keywords" Type="System.String" Path="Event/System/Keywords">70</Column><Column Name="Date and Time" Type="System.DateTime" Path="Event/System/TimeCreated/@SystemTime" Visible="">275</Column><Column Name="Source" Type="System.String" Path="Event/System/Provider/@Name" Visible="">185</Column><Column Name="Event ID" Type="System.UInt32" Path="Event/System/EventID" Visible="">185</Column><Column Name="Task Category" Type="System.String" Path="Event/System/Task" Visible="">188</Column><Column Name="User" Type="System.String" Path="Event/System/Security/@UserID">50</Column><Column Name="Operational Code" Type="System.String" Path="Event/System/Opcode">110</Column><Column Name="Log" Type="System.String" Path="Event/System/Channel">80</Column><Column Name="Computer" Type="System.String" Path="Event/System/Computer">170</Column><Column Name="Process ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessID">70</Column><Column Name="Thread ID" Type="System.UInt32" Path="Event/System/Execution/@ThreadID">70</Column><Column Name="Processor ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessorID">90</Column><Column Name="Session ID" Type="System.UInt32" Path="Event/System/Execution/@SessionID">70</Column><Column Name="Kernel Time" Type="System.UInt32" Path="Event/System/Execution/@KernelTime">80</Column><Column Name="User Time" Type="System.UInt32" Path="Event/System/Execution/@UserTime">70</Column><Column Name="Processor Time" Type="System.UInt32" Path="Event/System/Execution/@ProcessorTime">100</Column><Column Name="Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@ActivityID">85</Column><Column Name="Relative Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@RelatedActivityID">140</Column><Column Name="Event Source Name" Type="System.String" Path="Event/System/Provider/@EventSourceName">140</Column></Columns></ResultsConfig></ViewerConfig> "@ Add-Content -Path "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_4.xml" -Value $View_4 } # Sudden Shut down events $path_5 = "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_5.xml" if (-NOT (Test-Path $path_5)) { New-Item -Path $path_5 -ItemType File $View_5 = @" <ViewerConfig><QueryConfig><QueryParams><Simple><Channel>System</Channel><EventId>41,6008</EventId><RelativeTimeInfo>0</RelativeTimeInfo><BySource>False</BySource></Simple></QueryParams><QueryNode><Name LanguageNeutralValue="Sudden Shut down events">Sudden Shut down events</Name><Description>41= Unexpected Power loss or crash | 6008 = dirty shut down</Description><QueryList><Query Id="0" Path="System"><Select Path="System">*[System[(EventID=41 or EventID=6008)]]</Select></Query></QueryList></QueryNode></QueryConfig><ResultsConfig><Columns><Column Name="Level" Type="System.String" Path="Event/System/Level" Visible="">227</Column><Column Name="Keywords" Type="System.String" Path="Event/System/Keywords">70</Column><Column Name="Date and Time" Type="System.DateTime" Path="Event/System/TimeCreated/@SystemTime" Visible="">277</Column><Column Name="Source" Type="System.String" Path="Event/System/Provider/@Name" Visible="">187</Column><Column Name="Event ID" Type="System.UInt32" Path="Event/System/EventID" Visible="">187</Column><Column Name="Task Category" Type="System.String" Path="Event/System/Task" Visible="">188</Column><Column Name="User" Type="System.String" Path="Event/System/Security/@UserID">50</Column><Column Name="Operational Code" Type="System.String" Path="Event/System/Opcode">110</Column><Column Name="Log" Type="System.String" Path="Event/System/Channel">80</Column><Column Name="Computer" Type="System.String" Path="Event/System/Computer">170</Column><Column Name="Process ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessID">70</Column><Column Name="Thread ID" Type="System.UInt32" Path="Event/System/Execution/@ThreadID">70</Column><Column Name="Processor ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessorID">90</Column><Column Name="Session ID" Type="System.UInt32" Path="Event/System/Execution/@SessionID">70</Column><Column Name="Kernel Time" Type="System.UInt32" Path="Event/System/Execution/@KernelTime">80</Column><Column Name="User Time" Type="System.UInt32" Path="Event/System/Execution/@UserTime">70</Column><Column Name="Processor Time" Type="System.UInt32" Path="Event/System/Execution/@ProcessorTime">100</Column><Column Name="Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@ActivityID">85</Column><Column Name="Relative Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@RelatedActivityID">140</Column><Column Name="Event Source Name" Type="System.String" Path="Event/System/Provider/@EventSourceName">140</Column></Columns></ResultsConfig></ViewerConfig> "@ Add-Content -Path "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_5.xml" -Value $View_5 } # Code Integrity Operational events $path_6 = "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_6.xml" if (-NOT (Test-Path $path_6)) { New-Item -Path $path_6 -ItemType File $View_6 = @" <ViewerConfig><QueryConfig><QueryParams><Simple><Channel>Microsoft-Windows-CodeIntegrity/Operational</Channel><RelativeTimeInfo>0</RelativeTimeInfo><BySource>False</BySource></Simple></QueryParams><QueryNode><Name LanguageNeutralValue="Code Integrity Operational">Code Integrity Operational</Name><QueryList><Query Id="0" Path="Microsoft-Windows-CodeIntegrity/Operational"><Select Path="Microsoft-Windows-CodeIntegrity/Operational">*</Select></Query></QueryList></QueryNode></QueryConfig><ResultsConfig><Columns><Column Name="Level" Type="System.String" Path="Event/System/Level" Visible="">227</Column><Column Name="Keywords" Type="System.String" Path="Event/System/Keywords">70</Column><Column Name="Date and Time" Type="System.DateTime" Path="Event/System/TimeCreated/@SystemTime" Visible="">277</Column><Column Name="Source" Type="System.String" Path="Event/System/Provider/@Name" Visible="">187</Column><Column Name="Event ID" Type="System.UInt32" Path="Event/System/EventID" Visible="">187</Column><Column Name="Task Category" Type="System.String" Path="Event/System/Task" Visible="">188</Column><Column Name="User" Type="System.String" Path="Event/System/Security/@UserID">50</Column><Column Name="Operational Code" Type="System.String" Path="Event/System/Opcode">110</Column><Column Name="Log" Type="System.String" Path="Event/System/Channel">80</Column><Column Name="Computer" Type="System.String" Path="Event/System/Computer">170</Column><Column Name="Process ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessID">70</Column><Column Name="Thread ID" Type="System.UInt32" Path="Event/System/Execution/@ThreadID">70</Column><Column Name="Processor ID" Type="System.UInt32" Path="Event/System/Execution/@ProcessorID">90</Column><Column Name="Session ID" Type="System.UInt32" Path="Event/System/Execution/@SessionID">70</Column><Column Name="Kernel Time" Type="System.UInt32" Path="Event/System/Execution/@KernelTime">80</Column><Column Name="User Time" Type="System.UInt32" Path="Event/System/Execution/@UserTime">70</Column><Column Name="Processor Time" Type="System.UInt32" Path="Event/System/Execution/@ProcessorTime">100</Column><Column Name="Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@ActivityID">85</Column><Column Name="Relative Correlation Id" Type="System.Guid" Path="Event/System/Correlation/@RelatedActivityID">140</Column><Column Name="Event Source Name" Type="System.String" Path="Event/System/Provider/@EventSourceName">140</Column></Columns></ResultsConfig></ViewerConfig> "@ Add-Content -Path "C:\ProgramData\Microsoft\Event Viewer\Views\Hardening Script\View_6.xml" -Value $View_6 } # turn on "Show text suggestions when typing on the physical keyboard" for the current user, toggles the option in Windows settings ModifyRegistry -RegPath 'HKCU:\Software\Microsoft\Input\Settings' -RegName 'EnableHwkbTextPrediction' -RegValue '1' # turn on "Multilingual text suggestions" for the current user, toggles the option in Windows settings ModifyRegistry -RegPath 'HKCU:\Software\Microsoft\Input\Settings' -RegName 'MultilingualEnabled' -RegValue '1' # turn off sticky key shortcut of pressing shift key 5 time fast - value is type string, can't use ModifyRegistry Function $RegistryPath = 'HKCU:\Control Panel\Accessibility\StickyKeys' $Name = 'Flags' $Value = '506' If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null } New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force } "No" { break } "Exit" { exit } } # ========================================================================================================================= # ====================================================End of Non-Admin Commands============================================ # ========================================================================================================================= #endregion Non-Admin-Commands $infomsg = "`r`n" + "################################################################################################`r`n" + "### Please Restart your device to completely apply the security measures and Group Policies ###`r`n" + "################################################################################################`r`n" Write-Host $infomsg -ForegroundColor Cyan |