Edit-WDACConfig.psm1
#requires -version 7.3.3 Function Test-IsAdmin { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal $identity $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) } if (-NOT (Test-IsAdmin)) { write-host "Administrator privileges Required" -ForegroundColor Magenta break } function Edit-WDACConfig { [CmdletBinding( DefaultParameterSetName = "set1", HelpURI = "https://github.com/HotCakeX/Harden-Windows-Security/wiki/WDAC-Module", SupportsShouldProcess = $true, PositionalBinding = $false, ConfirmImpact = 'High' )] Param( [Parameter(Mandatory = $false, ParameterSetName = "set1", Position = 0, ValueFromPipeline = $true)][switch]$AllowNewApps_AuditEvents, [Parameter(Mandatory = $false, ParameterSetName = "set2", Position = 0, ValueFromPipeline = $true)][switch]$AllowNewApps, [Parameter(Mandatory = $true, ParameterSetName = "set1", ValueFromPipelineByPropertyName = $true)] [string]$SuppPolicyName, [Parameter(Mandatory = $true, ParameterSetName = "set1", ValueFromPipelineByPropertyName = $true)] [string[]]$PolicyPaths, [Parameter(Mandatory = $false, ParameterSetName = "set1")] [switch]$Debugmode, [ValidateRange(1024KB, [int64]::MaxValue)] [Parameter(Mandatory = $false, ParameterSetName = "set1")] [Int64]$LogSize, [Parameter(Mandatory = $false)][switch]$SkipVersionCheck ) $ErrorActionPreference = 'Stop' <# if (-NOT $SkipVersionCheck) { # Make sure the latest version of the module is installed and if not, automatically update it, clean up any old versions $currentversion = (Test-modulemanifest "$psscriptroot\New-WDACConfig.psd1").Version.ToString() try { $latestversion = Invoke-RestMethod -Uri "https://raw.githubusercontent.com/HotCakeX/Harden-Windows-Security/main/New-WDACConfig/version.txt" } catch { Write-Error "Couldn't verify if the latest version of the module is installed, please check your Internet connection. You can optionally bypass the online check by using -SkipVersionCheck parameter." break } if (-NOT ($currentversion -eq $latestversion)) { Write-Host "The currently installed module's version is $currentversion while the latest version is $latestversion - Auto Updating the module now and will run your command after that 💓" Remove-Module -Name New-WDACConfig -Force Uninstall-Module -Name New-WDACConfig -AllVersions -Force Install-Module -Name New-WDACConfig -RequiredVersion $latestversion -Force Import-Module -Name New-WDACConfig -RequiredVersion $latestversion -Force -Global } } #> #region Misc-Functions # Increase Code Integrity Operational Event Logs size from the default 1MB to user defined size function Set-LogSize { [CmdletBinding()] param ([int64]$LogSize) $logName = 'Microsoft-Windows-CodeIntegrity/Operational' $log = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration $logName $log.MaximumSizeInBytes = $LogSize $log.IsEnabled = $true $log.SaveChanges() } if ($AllowNewApps) { # remove any possible files from previous runs Remove-Item -Path ".\ProgramDir_ScanResults*.xml" -Force -ErrorAction SilentlyContinue Remove-Item -Path ".\SupplementalPolicy$SuppPolicyName.xml" -Force -ErrorAction SilentlyContinue $ProgramDir_ScanResultsArray = @() #Initiate Live Audit Mode foreach ($PolicyPath in $PolicyPaths) { # defining Base policy $xml = [xml](Get-Content $PolicyPath) $PolicyID = $xml.SiPolicy.PolicyID $PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq "PolicyInfo" -and $_.valuename -eq "Name" -and $_.key -eq "Information" }).value.string # Remove any cip file if there is any Remove-Item -Path ".\$PolicyID.cip" -ErrorAction SilentlyContinue Set-RuleOption -FilePath $PolicyPath -Option 3 ConvertFrom-CIPolicy $PolicyPath "$PolicyID.cip" | Out-Null CiTool --update-policy ".\$PolicyID.cip" -json Remove-Item ".\$PolicyID.cip" -Force Write-host "`n`nThe Base policy with the following details has been Re-Deployed in Audit Mode:" -ForegroundColor Green Write-Output "PolicyName = $PolicyName" Write-Output "PolicyGUID = $PolicyID" #User Interaction Write-host "`nAudit mode deployed, start installing your programs now" -ForegroundColor Magenta Write-Host "When you've finished installing programs, Press Enter to start selecting program directories to scan`n" -ForegroundColor Blue Pause $ProgramsPaths = @() Write-host "`nSelect program directories to scan`n" -ForegroundColor Cyan do { [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null $OBJ = New-Object System.Windows.Forms.FolderBrowserDialog $OBJ.InitialDirectory = "$env:SystemDrive" $OBJ.Description = $Description $Spawn = New-Object System.Windows.Forms.Form -Property @{TopMost = $true } $Show = $OBJ.ShowDialog($Spawn) If ($Show -eq "OK") { $ProgramsPaths += $OBJ.SelectedPath } Else { break } } while ($true) if (-NOT ($ProgramsPaths.count -eq 0)) { Write-Host "Here are the paths you selected:" -ForegroundColor Yellow $ProgramsPaths | ForEach-Object { $_ } #Process Program Folders From User input for ($i = 0; $i -lt $ProgramsPaths.Count; $i++) { New-CIPolicy -FilePath ".\ProgramDir_ScanResults$($i).xml" -ScanPath $ProgramsPaths[$i] -Level SignedVersion -Fallback FilePublisher, Hash -UserPEs -MultiplePolicyFormat -UserWriteablePaths } # merge-cipolicy accept arrays - collecting all the policy files created by scanning user specified folders $ProgramDir_ScanResults = Get-ChildItem ".\" | Where-Object { $_.Name -like 'ProgramDir_ScanResults*.xml' } foreach ($file in $ProgramDir_ScanResults) { $ProgramDir_ScanResultsArray += $file.FullName } Merge-CIPolicy -PolicyPaths $ProgramDir_ScanResultsArray -OutputFilePath ".\SupplementalPolicy$SuppPolicyName.xml" | Out-Null #Re-Deploy-Basepolicy-in-Enforcement-mode Set-RuleOption -FilePath $PolicyPath -Option 3 -Delete ConvertFrom-CIPolicy $PolicyPath "$PolicyID.cip" | Out-Null CiTool --update-policy ".\$PolicyID.cip" -json Remove-Item ".\$PolicyID.cip" -Force Write-host "`n`nThe Base policy with the following details has been Re-Deployed in Enforcement Mode:" -ForegroundColor Green Write-Output "PolicyName = $PolicyName" Write-Output "PolicyGUID = $PolicyID`n" Remove-Item -Path ".\ProgramDir_ScanResults*.xml" -Force #Supplemental-policy-processing-and-deployment $SuppPolicyPath = ".\SupplementalPolicy$SuppPolicyName.xml" $SuppPolicyID = Set-CIPolicyIdInfo -FilePath $SuppPolicyPath -PolicyName "Supplemental Policy $SuppPolicyName made on $(Get-Date -Format 'MM-dd-yyyy')" -ResetPolicyID -BasePolicyToSupplementPath $PolicyPath $SuppPolicyID = $SuppPolicyID.Substring(11) # Make sure policy rule options that don't belong to a Supplemental policy don't exit @(0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 15, 16, 17, 19, 20) | ForEach-Object { Set-RuleOption -FilePath $SuppPolicyPath -Option $_ -Delete } Set-HVCIOptions -Strict -FilePath $SuppPolicyPath Set-CIPolicyVersion -FilePath $SuppPolicyPath -Version "1.0.0.0" ConvertFrom-CIPolicy $SuppPolicyPath "$SuppPolicyID.cip" | Out-Null CiTool --update-policy ".\$SuppPolicyID.cip" -json Remove-Item ".\$SuppPolicyID.cip" -Force Write-host "`nSupplemental policy with the following details has been Deployed in Enforcement Mode.`n" -ForegroundColor Green [PSCustomObject]@{ SupplementalPolicyName = $SuppPolicyName SupplementalPolicyGUID = $SuppPolicyID } } # If no program path was provied else { Write-Host "`nNo program folder was selected, reverting the changes and quitting...`n" -ForegroundColor Magenta #Re-Deploy Basepolicy in Enforcement mode Set-RuleOption -FilePath $PolicyPath -Option 3 -Delete ConvertFrom-CIPolicy $PolicyPath "$PolicyID.cip" | Out-Null CiTool --update-policy ".\$PolicyID.cip" -json Remove-Item ".\$PolicyID.cip" -Force Write-host "`n`nThe Base policy with the following details has been Re-Deployed in Enforcement Mode:" -ForegroundColor Green Write-Output "PolicyName = $PolicyName" Write-Output "PolicyGUID = $PolicyID`n" break } } } } # Set PSReadline tab completion to complete menu for easier access to available parameters - Only for the current session Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete # argument tab auto-completion for Policy Paths to show only .xml files and only base policies $ArgumentCompleterPolicyPaths = { Get-ChildItem | where-object { $_.extension -like '*.xml' } | foreach-object { return "`"$_`"" } } Register-ArgumentCompleter -CommandName "New-WDACConfig" -ParameterName "PolicyPaths" -ScriptBlock $ArgumentCompleterPolicyPaths |