Skip to content

Commit a0b7d91

Browse files
committed
WDACConfig module update v0.2.1
1. Added -AllowFileNameFallbacks parameter by default when creating policies. It's a great parameter that helps include files that do not have an OriginalFileName. 2. Fixed the Microsoft recommended Block lists URLs in the code because they were changed and had to be updated. #83 3. Improved code quality (Security, readability, typos in the comments etc.)
1 parent d05b88f commit a0b7d91

16 files changed

+156
-155
lines changed

WDACConfig/ArgumentCompleters.ps1

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# argument tab auto-completion for SignToolPath param to show only .exe files in the current directory
2-
$ArgumentCompleterSignToolPath = {
2+
[scriptblock]$ArgumentCompleterSignToolPath = {
33
Get-ChildItem | Where-Object { $_.extension -like '*.exe' } | ForEach-Object { return "`"$_`"" }
44
}
55

66
# argument tab auto-completion for CertPath param to show only .cer files in current directory and 2 sub-directories recursively
7-
$ArgumentCompleterCertPath = {
7+
[scriptblock]$ArgumentCompleterCertPath = {
88
# Note the use of -Depth 1
99
# Enclosing the $results = ... assignment in (...) also passes the value through.
1010
($results = Get-ChildItem -Depth 2 -Filter *.cer | ForEach-Object { "`"$_`"" })
@@ -16,7 +16,7 @@ $ArgumentCompleterCertPath = {
1616

1717
# argument tab auto-completion for Policy Paths to show only .xml files and only suggest files that haven't been already selected by user
1818
# https://stackoverflow.com/questions/76141864/how-to-make-a-powershell-argument-completer-that-only-suggests-files-not-already/76142865
19-
$ArgumentCompleterPolicyPaths = {
19+
[scriptblock]$ArgumentCompleterPolicyPaths = {
2020
# Get the current command and the already bound parameters
2121
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
2222

@@ -39,15 +39,15 @@ $ArgumentCompleterPolicyPaths = {
3939
}
4040

4141
# argument tab auto-completion for Certificate common name
42-
$ArgumentCompleterCertificateCN = {
42+
[scriptblock]$ArgumentCompleterCertificateCN = {
4343
$certs = foreach ($cert in (Get-ChildItem 'Cert:\CurrentUser\my')) {
4444
(($cert.Subject -split ',' | Select-Object -First 1) -replace 'CN=', '').Trim()
4545
}
4646
$certs | ForEach-Object { return "`"$_`"" }
4747
}
4848

4949
# Argument tab auto-completion for installed Appx package names
50-
$ArgumentCompleterAppxPackageNames = {
50+
[scriptblock]$ArgumentCompleterAppxPackageNames = {
5151
# Get the current command and the already bound parameters
5252
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
5353
# Get the app package names that match the word to complete
@@ -57,7 +57,7 @@ $ArgumentCompleterAppxPackageNames = {
5757
}
5858

5959
# argument tab auto-completion for Base Policy Paths to show only .xml files and only suggest files that haven't been already selected by user
60-
$ArgumentCompleterPolicyPathsBasePoliciesOnly = {
60+
[scriptblock]$ArgumentCompleterPolicyPathsBasePoliciesOnly = {
6161
# Get the current command and the already bound parameters
6262
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
6363

@@ -87,7 +87,7 @@ $ArgumentCompleterPolicyPathsBasePoliciesOnly = {
8787
}
8888

8989
# argument tab auto-completion for Supplemental Policy Paths to show only .xml files and only suggest files that haven't been already selected by user
90-
$ArgumentCompleterPolicyPathsSupplementalPoliciesOnly = {
90+
[scriptblock]$ArgumentCompleterPolicyPathsSupplementalPoliciesOnly = {
9191
# Get the current command and the already bound parameters
9292
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
9393

@@ -117,7 +117,7 @@ $ArgumentCompleterPolicyPathsSupplementalPoliciesOnly = {
117117
}
118118

119119
# Opens Folder picker GUI so that user can select folders to be processed
120-
$ArgumentCompleterFolderPathsPicker = {
120+
[scriptblock]$ArgumentCompleterFolderPathsPicker = {
121121
# Load the System.Windows.Forms assembly
122122
Add-Type -AssemblyName System.Windows.Forms
123123
# non-top-most, works better with window focus
@@ -128,7 +128,7 @@ $ArgumentCompleterFolderPathsPicker = {
128128
}
129129

130130
# Opens File picker GUI so that user can select an .exe file - for SignTool.exe
131-
$ArgumentCompleterExeFilePathsPicker = {
131+
[scriptblock]$ArgumentCompleterExeFilePathsPicker = {
132132
# Load the System.Windows.Forms assembly
133133
Add-Type -AssemblyName System.Windows.Forms
134134
# Create a new OpenFileDialog object
@@ -144,7 +144,7 @@ $ArgumentCompleterExeFilePathsPicker = {
144144
}
145145

146146
# Opens File picker GUI so that user can select a .cer file
147-
$ArgumentCompleterCerFilePathsPicker = {
147+
[scriptblock]$ArgumentCompleterCerFilePathsPicker = {
148148
# Load the System.Windows.Forms assembly
149149
Add-Type -AssemblyName System.Windows.Forms
150150
# Create a new OpenFileDialog object
@@ -160,7 +160,7 @@ $ArgumentCompleterCerFilePathsPicker = {
160160
}
161161

162162
# Opens File picker GUI so that user can select a .xml file
163-
$ArgumentCompleterXmlFilePathsPicker = {
163+
[scriptblock]$ArgumentCompleterXmlFilePathsPicker = {
164164
# Load the System.Windows.Forms assembly
165165
Add-Type -AssemblyName System.Windows.Forms
166166
# Create a new OpenFileDialog object

WDACConfig/Confirm-WDACConfig.psm1

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ function Confirm-WDACConfig {
2424
if (-NOT $SkipVersionCheck) { . Update-self }
2525

2626
# Script block to show only non-system Base policies
27-
$OnlyBasePoliciesBLOCK = {
27+
[scriptblock]$OnlyBasePoliciesBLOCK = {
2828
$BasePolicies = (CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.IsSystemPolicy -ne 'True' } | Where-Object { $_.PolicyID -eq $_.BasePolicyID }
2929
&$WriteLavender "`nThere are currently $(($BasePolicies.count)) Non-system Base policies deployed"
3030
$BasePolicies
3131
}
3232
# Script block to show only non-system Supplemental policies
33-
$OnlySupplementalPoliciesBLOCK = {
33+
[scriptblock]$OnlySupplementalPoliciesBLOCK = {
3434
$SupplementalPolicies = (CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.IsSystemPolicy -ne 'True' } | Where-Object { $_.PolicyID -ne $_.BasePolicyID }
3535
&$WriteLavender "`nThere are currently $(($SupplementalPolicies.count)) Non-system Supplemental policies deployed`n"
3636
$SupplementalPolicies
@@ -52,13 +52,13 @@ function Confirm-WDACConfig {
5252
if ($CheckSmartAppControlStatus) {
5353
Get-MpComputerStatus | Select-Object -Property SmartAppControlExpiration, SmartAppControlState
5454
if ((Get-MpComputerStatus).SmartAppControlState -eq 'Eval') {
55-
&$WritePink "Smart App Control is in Evaluation mode.`n"
55+
&$WritePink "`nSmart App Control is in Evaluation mode."
5656
}
5757
elseif ((Get-MpComputerStatus).SmartAppControlState -eq 'On') {
58-
&$WritePink "Smart App Control is turned on.`n"
58+
&$WritePink "`nSmart App Control is turned on."
5959
}
6060
elseif ((Get-MpComputerStatus).SmartAppControlState -eq 'Off') {
61-
&$WritePink "Smart App Control is turned off.`n"
61+
&$WritePink "`nSmart App Control is turned off."
6262
}
6363
}
6464
}

WDACConfig/Deploy-SignedWDACConfig.psm1

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ function Deploy-SignedWDACConfig {
66
ConfirmImpact = 'High'
77
)]
88
Param(
9-
[ValidatePattern('\.cer$')]
10-
[ValidateScript({ Test-Path $_ -PathType 'Leaf' }, ErrorMessage = 'The path you selected is not a file path.')]
11-
[parameter(Mandatory = $false)][System.String]$CertPath,
12-
139
[ValidatePattern('\.xml$')]
1410
[ValidateScript({ Test-Path $_ -PathType 'Leaf' }, ErrorMessage = 'The path you selected is not a file path.')]
1511
[parameter(Mandatory = $true)][System.String[]]$PolicyPaths,
12+
13+
[ValidatePattern('\.cer$')]
14+
[ValidateScript({ Test-Path $_ -PathType 'Leaf' }, ErrorMessage = 'The path you selected is not a file path.')]
15+
[parameter(Mandatory = $false)][System.String]$CertPath,
1616

1717
[ValidateScript({
1818
$certs = foreach ($cert in (Get-ChildItem 'Cert:\CurrentUser\my')) {
@@ -104,9 +104,9 @@ function Deploy-SignedWDACConfig {
104104
foreach ($PolicyPath in $PolicyPaths) {
105105

106106
$xml = [xml](Get-Content $PolicyPath)
107-
$PolicyType = $xml.SiPolicy.PolicyType
108-
$PolicyID = $xml.SiPolicy.PolicyID
109-
$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
107+
[System.String]$PolicyType = $xml.SiPolicy.PolicyType
108+
[System.String]$PolicyID = $xml.SiPolicy.PolicyID
109+
[System.String]$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
110110
Remove-Item -Path ".\$PolicyID.cip" -ErrorAction SilentlyContinue
111111
if ($PolicyType -eq 'Supplemental Policy') {
112112
Add-SignerRule -FilePath $PolicyPath -CertificatePath $CertPath -Update -User -Kernel
@@ -133,7 +133,7 @@ function Deploy-SignedWDACConfig {
133133
Remove-Item ".\$PolicyID.cip" -Force
134134
Rename-Item "$PolicyID.cip.p7" -NewName "$PolicyID.cip" -Force
135135
CiTool --update-policy ".\$PolicyID.cip" -json | Out-Null
136-
Write-Host "`n`npolicy with the following details has been Signed and Deployed in Enforced Mode:" -ForegroundColor Green
136+
Write-Host "`npolicy with the following details has been Signed and Deployed in Enforced Mode:" -ForegroundColor Green
137137
Write-Output "PolicyName = $PolicyName"
138138
Write-Output "PolicyGUID = $PolicyID`n"
139139
Remove-Item -Path ".\$PolicyID.cip" -Force

WDACConfig/Edit-SignedWDACConfig.psm1

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ function Edit-SignedWDACConfig {
254254
Remove-Item -Path ".\SupplementalPolicy$SuppPolicyName.xml" -Force -ErrorAction SilentlyContinue
255255
# Get the current date so that instead of the entire event viewer logs, only audit logs created after running this module will be captured
256256
# The notice about variable being assigned and never used should be ignored - it's being dot-sourced from Resources file
257-
$Date = Get-Date
257+
[datetime]$Date = Get-Date
258258
# An empty array that holds the Policy XML files - This array will eventually be used to create the final Supplemental policy
259-
$PolicyXMLFilesArray = @()
259+
[System.Array]$PolicyXMLFilesArray = @()
260260

261261
################################### Initiate Live Audit Mode ###################################
262262

@@ -269,8 +269,8 @@ function Edit-SignedWDACConfig {
269269

270270
# Defining Base policy
271271
$xml = [xml](Get-Content $PolicyPath)
272-
$PolicyID = $xml.SiPolicy.PolicyID
273-
$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
272+
[System.String]$PolicyID = $xml.SiPolicy.PolicyID
273+
[System.String]$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
274274

275275
# Remove any cip file if there is any
276276
Remove-Item -Path '.\*.cip' -Force -ErrorAction SilentlyContinue
@@ -335,7 +335,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
335335
Pause
336336

337337
# Store the program paths that user browses for in an array
338-
$ProgramsPaths = @()
338+
[System.Array]$ProgramsPaths = @()
339339
Write-Host "`nSelect program directories to scan" -ForegroundColor Cyan
340340
# Showing folder picker GUI to the user for folder path selection
341341
do {
@@ -469,7 +469,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
469469
# Any other attempts such as "Get-FileHash" or "Get-AuthenticodeSignature" fail and ConfigCI Module cmdlets totally ignore these files and do not create allow rules for them
470470

471471
# Finding the file(s) first and storing them in an array
472-
$ExesWithNoHash = @()
472+
[System.Array]$ExesWithNoHash = @()
473473
# looping through each user-selected path(s)
474474
foreach ($ProgramsPath in $ProgramsPaths) {
475475
# Making sure the currently processing path has any .exe in it
@@ -496,7 +496,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
496496
Write-Debug -Message "The following Kernel protected files detected, creating allow rules for them:`n"
497497
if ($Debug) { $ExesWithNoHash | ForEach-Object { Write-Debug -Message "$_" } }
498498

499-
$KernelProtectedHashesBlock = {
499+
[scriptblock]$KernelProtectedHashesBlock = {
500500
foreach ($event in Get-WinEvent -FilterHashtable @{LogName = 'Microsoft-Windows-CodeIntegrity/Operational'; ID = 3076 } -ErrorAction SilentlyContinue | Where-Object { $_.TimeCreated -ge $Date } ) {
501501
$xml = [xml]$event.toxml()
502502
$xml.event.eventdata.data |
@@ -621,7 +621,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
621621
Remove-Item -Path '.\ProgramDir_ScanResults*.xml' -Force -ErrorAction SilentlyContinue
622622
Remove-Item -Path ".\SupplementalPolicy$SuppPolicyName.xml" -Force -ErrorAction SilentlyContinue
623623
# An empty array that holds the Policy XML files - This array will eventually be used to create the final Supplemental policy
624-
$PolicyXMLFilesArray = @()
624+
[System.Array]$PolicyXMLFilesArray = @()
625625

626626
#Initiate Live Audit Mode
627627

@@ -634,8 +634,8 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
634634

635635
# Defining Base policy
636636
$xml = [xml](Get-Content $PolicyPath)
637-
$PolicyID = $xml.SiPolicy.PolicyID
638-
$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
637+
[System.String]$PolicyID = $xml.SiPolicy.PolicyID
638+
[System.String]$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
639639

640640
# Remove any cip file if there is any
641641
Remove-Item -Path '.\*.cip' -Force -ErrorAction SilentlyContinue
@@ -700,7 +700,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
700700
Pause
701701

702702
# Store the program paths that user browses for in an array
703-
$ProgramsPaths = @()
703+
[System.Array]$ProgramsPaths = @()
704704
Write-Host "`nSelect program directories to scan`n" -ForegroundColor Cyan
705705
# Showing folder picker GUI to the user for folder path selection
706706
do {
@@ -906,17 +906,19 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
906906
Copy-Item -Path 'C:\Windows\schemas\CodeIntegrity\ExamplePolicies\DefaultWindows_Enforced.xml' -Destination '.\DefaultWindows_Enforced.xml'
907907

908908
# Allowing SignTool to be able to run after Default Windows base policy is deployed
909-
&$WriteViolet "`nCreating allow rules for SignTool.exe in the DefaultWindows base policy so you can continue using it after deploying the DefaultWindows base policy."
909+
&$WriteTeaGreen "`nCreating allow rules for SignTool.exe in the DefaultWindows base policy so you can continue using it after deploying the DefaultWindows base policy."
910910
New-Item -Path "$env:TEMP\TemporarySignToolFile" -ItemType Directory -Force | Out-Null
911911
Copy-Item -Path $SignToolPathFinal -Destination "$env:TEMP\TemporarySignToolFile" -Force
912-
New-CIPolicy -ScanPath "$env:TEMP\TemporarySignToolFile" -Level FilePublisher -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -FilePath .\SignTool.xml
912+
New-CIPolicy -ScanPath "$env:TEMP\TemporarySignToolFile" -Level FilePublisher -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -AllowFileNameFallbacks -FilePath .\SignTool.xml
913+
# Due to a bug Have to repeat this process twice: https://github.com/MicrosoftDocs/WDAC-Toolkit/issues/278
914+
New-CIPolicy -ScanPath "$env:TEMP\TemporarySignToolFile" -Level FilePublisher -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -AllowFileNameFallbacks -FilePath .\SignTool.xml
913915
# Delete the Temporary folder in the TEMP folder
914-
Remove-Item -Recurse -Path "$env:TEMP\TemporarySignToolFile" -Force
916+
if (!$Debug) { Remove-Item -Recurse -Path "$env:TEMP\TemporarySignToolFile" -Force }
915917

916918
# Scan PowerShell core directory and add them to the Default Windows base policy so that the module can be used after it's been deployed
917919
if (Test-Path 'C:\Program Files\PowerShell') {
918920
&$WriteViolet "`nCreating allow rules for PowerShell in the DefaultWindows base policy so you can continue using this module after deploying it."
919-
New-CIPolicy -ScanPath 'C:\Program Files\PowerShell' -Level FilePublisher -NoScript -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -FilePath .\AllowPowerShell.xml
921+
New-CIPolicy -ScanPath 'C:\Program Files\PowerShell' -Level FilePublisher -NoScript -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -AllowFileNameFallbacks -FilePath .\AllowPowerShell.xml
920922
Merge-CIPolicy -PolicyPaths .\DefaultWindows_Enforced.xml, .\AllowPowerShell.xml, .\SignTool.xml, '.\Microsoft recommended block rules.xml' -OutputFilePath .\BasePolicy.xml | Out-Null
921923
}
922924
else {
@@ -931,8 +933,10 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
931933
if ($UpdateBasePolicy -and $RequireEVSigners) { Set-RuleOption -FilePath .\BasePolicy.xml -Option 8 }
932934

933935
# Remove the extra files create during module operation that are no longer necessary
934-
Remove-Item '.\AllowPowerShell.xml', '.\SignTool.xml', '.\AllowMicrosoft.xml', '.\DefaultWindows_Enforced.xml' -Force -ErrorAction SilentlyContinue
935-
Remove-Item '.\Microsoft recommended block rules.xml' -Force
936+
if (!$Debug) {
937+
Remove-Item '.\AllowPowerShell.xml', '.\SignTool.xml', '.\AllowMicrosoft.xml', '.\DefaultWindows_Enforced.xml' -Force -ErrorAction SilentlyContinue
938+
Remove-Item '.\Microsoft recommended block rules.xml' -Force
939+
}
936940

937941
# Get the policy ID of the currently deployed base policy based on the policy name that user selected
938942
$CurrentID = ((CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.IsSystemPolicy -ne 'True' } | Where-Object { $_.Friendlyname -eq $CurrentBasePolicyName }).BasePolicyID
@@ -976,7 +980,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
976980
Remove-Item ".\$CurrentID.cip" -Force
977981
Remove-Item $PolicyFiles[$NewBasePolicyType] -Force -ErrorAction SilentlyContinue
978982
Rename-Item -Path '.\BasePolicy.xml' -NewName $PolicyFiles[$NewBasePolicyType]
979-
&$WriteSubtleRainbow "Base Policy has been successfully updated to $NewBasePolicyType"
983+
&$WritePink "Base Policy has been successfully updated to $NewBasePolicyType"
980984
&$WriteLavender 'Keep in mind that your previous policy path saved in User Configurations is no longer valid as you just changed your Base policy.'
981985
}
982986
}

0 commit comments

Comments
 (0)