Skip to content

Commit 51a3c1e

Browse files
Merge pull request #185 from nyanhp/applockerpipe
Add AppLocker IaC project template
2 parents c1ea1d4 + d7b0abc commit 51a3c1e

File tree

24 files changed

+746
-0
lines changed

24 files changed

+746
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
on:
3+
push:
4+
branches:
5+
- main
6+
7+
jobs:
8+
publish:
9+
10+
runs-on: windows-latest
11+
12+
steps:
13+
- uses: actions/checkout@v1
14+
- name: Install Prerequisites
15+
run: .\build\prerequisites.ps1 -BuildWorker -DependencyPath (Join-Path $env:GITHUB_WORKSPACE build\requiredModules.psd1)
16+
shell: powershell
17+
- name: Validate Configuration Data
18+
run: .\build\validate.ps1 -TestType ConfigurationData -DependencyPath (Join-Path $env:GITHUB_WORKSPACE build\requiredModules.psd1) -ProjectRoot $env:GITHUB_WORKSPACE
19+
shell: powershell
20+
- name: Build
21+
run: .\build\build.ps1 -IncludeRsop -DependencyPath (Join-Path $env:GITHUB_WORKSPACE build\requiredModules.psd1) -SourcePath (Join-Path $env:GITHUB_WORKSPACE configurationdata) -OutputPath (Join-Path $env:GITHUB_WORKSPACE output)
22+
shell: powershell
23+
- uses: actions/upload-artifact@v3
24+
with:
25+
name: build-artifacts
26+
path: |
27+
.\output\rsop
28+
.\output\policies
29+
- name: Publish
30+
run: .\build\publish.ps1
31+
shell: powershell
32+
- name: Validate Integration Tests
33+
run: .\build\validate.ps1 -TestType Integration -DependencyPath (Join-Path $env:GITHUB_WORKSPACE build\requiredModules.psd1) -ProjectRoot $env:GITHUB_WORKSPACE
34+
shell: powershell
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
on: [pull_request]
2+
3+
jobs:
4+
validate:
5+
6+
runs-on: windows-latest
7+
8+
steps:
9+
- uses: actions/checkout@v1
10+
- name: Install Prerequisites
11+
run: .\build\prerequisites.ps1 -BuildWorker -DependencyPath (Join-Path $env:GITHUB_WORKSPACE build\requiredModules.psd1)
12+
shell: powershell
13+
- name: Validate Configuration Data
14+
run: .\build\validate.ps1 -TestType ConfigurationData -DependencyPath (Join-Path $env:GITHUB_WORKSPACE build\requiredModules.psd1) -ProjectRoot $env:GITHUB_WORKSPACE
15+
shell: powershell
16+
- name: Build
17+
run: .\build\build.ps1 -IncludeRsop -DependencyPath (Join-Path $env:GITHUB_WORKSPACE build\requiredModules.psd1) -SourcePath (Join-Path $env:GITHUB_WORKSPACE configurationdata) -OutputPath (Join-Path $env:GITHUB_WORKSPACE output)
18+
shell: powershell
19+
- uses: actions/upload-artifact@v3
20+
with:
21+
name: build-artifacts
22+
path: |
23+
.\output\rsop
24+
.\output\policies

templates/AppLockerProject/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
output
2+
testresults.xml
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
param (
2+
$Path
3+
)
4+
5+
New-PSMDTemplate -ReferencePath "$PSScriptRoot" -OutPath $Path
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@{
2+
TemplateName = 'AppLockerProject'
3+
Version = "1.0.0"
4+
AutoIncrementVersion = $true
5+
Tags = 'module','psframework', 'applocker'
6+
Author = 'Jan-Hendrik Peters'
7+
Description = 'PowerShell Framework based AppLocker CI template'
8+
Exclusions = @("PSMDInvoke.ps1", ".PSMDDependency") # Contains list of files - relative path to root - to ignore when building the template
9+
Scripts = @{ }
10+
NoFolder = $true
11+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
trigger:
2+
branches:
3+
include:
4+
- main
5+
6+
jobs:
7+
- job: Build
8+
displayName: 'Build AppLocker Artifacts'
9+
pool:
10+
name: Default
11+
steps:
12+
- task: PowerShell@2
13+
name: prereq
14+
displayName: 'Download prerequisites'
15+
inputs:
16+
filePath: '.\build\prerequisites.ps1'
17+
arguments: '-DependencyPath (Join-Path $(Build.SourcesDirectory) build\requiredModules.psd1)'
18+
- task: PowerShell@2
19+
name: validateyaml
20+
displayName: Validate Configuration Data
21+
inputs:
22+
filePath: '.\build\validate.ps1'
23+
arguments: '-TestType ConfigurationData -DependencyPath (Join-Path $(Build.SourcesDirectory) build\requiredModules.psd1) -ProjectRoot $(Build.SourcesDirectory)'
24+
- task: PowerShell@2
25+
name: buildpolicy
26+
displayName: Build policy XML
27+
inputs:
28+
filePath: '.\build\build.ps1'
29+
arguments: '-IncludeRsop -DependencyPath (Join-Path $(Build.SourcesDirectory) build\requiredModules.psd1) -SourcePath (Join-Path $(Build.SourcesDirectory) configurationdata) -OutputPath (Join-Path $(Build.SourcesDirectory) output)'
30+
- task: PublishBuildArtifacts@1
31+
displayName: 'Publish Policy XML Files'
32+
inputs:
33+
PathtoPublish: 'output/Policies'
34+
ArtifactName: Policies
35+
- task: PublishBuildArtifacts@1
36+
displayName: 'Publish Policy RSOP Files'
37+
inputs:
38+
PathtoPublish: 'output/Rsop'
39+
ArtifactName: Rsop
40+
- task: PublishTestResults@2
41+
displayName: 'Publish Configuration Data Test Results'
42+
condition: succeededOrFailed()
43+
inputs:
44+
testResultsFormat: 'NUnit'
45+
testResultsFiles: 'tests/testresults.xml'
46+
mergeTestResults: true
47+
failTaskOnFailedTests: true
48+
testRunTitle: 'Configuration Data Tests'
49+
- deployment: Prod
50+
dependsOn: Build
51+
displayName: Prod Deployment
52+
environment: Prod
53+
pool:
54+
name: Default
55+
strategy:
56+
runOnce:
57+
deploy:
58+
steps:
59+
- task: DownloadBuildArtifacts@0
60+
displayName: 'Download Build Artifact: Rsop'
61+
inputs:
62+
buildType: 'current'
63+
artifactName: Rsop
64+
downloadPath: $(Build.SourcesDirectory)
65+
- task: DownloadBuildArtifacts@0
66+
displayName: 'Download Build Artifact: Policies'
67+
inputs:
68+
buildType: 'current'
69+
artifactName: Policies
70+
downloadPath: $(Build.SourcesDirectory)
71+
- task: PowerShell@2
72+
name: publishpolicies
73+
displayName: Publish policies
74+
inputs:
75+
filePath: '.\build\publish.ps1'
76+
arguments: '-DependencyPath (Join-Path $(Build.SourcesDirectory) build\requiredModules.psd1) -SourcePath (Join-Path $(Build.SourcesDirectory) configurationdata) -OutputPath (Join-Path $(Build.SourcesDirectory) output)'
77+
- task: PowerShell@2
78+
name: validateintegration
79+
displayName: Validate Integration
80+
inputs:
81+
filePath: '.\build\validate.ps1'
82+
arguments: '-TestType Integration -DependencyPath (Join-Path $(Build.SourcesDirectory) build\requiredModules.psd1) -ProjectRoot $(Build.SourcesDirectory)'
83+
- task: PublishTestResults@2
84+
displayName: 'Publish Integration Test Results'
85+
condition: succeededOrFailed()
86+
inputs:
87+
testResultsFormat: 'NUnit'
88+
testResultsFiles: 'tests/testresults.xml'
89+
mergeTestResults: true
90+
failTaskOnFailedTests: true
91+
testRunTitle: 'Integration Tests'
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
2+
param
3+
(
4+
[string]
5+
$DependencyPath = (Resolve-Path "$PSScriptRoot\requiredModules.psd1").Path,
6+
7+
[string]
8+
$SourcePath = "$PSScriptRoot\..\configurationdata",
9+
10+
[string]
11+
$OutputPath = "$PSScriptRoot\..\output",
12+
13+
[switch]
14+
$IncludeRsop
15+
)
16+
17+
$psdependConfig = Import-PowerShellDataFile -Path $DependencyPath
18+
$modPath = Resolve-Path -Path $psdependConfig.PSDependOptions.Target
19+
$modOld = $env:PSModulePath
20+
$pathSeparator = [System.IO.Path]::PathSeparator
21+
$env:PSModulePath = "$modPath$pathSeparator$modOld"
22+
23+
$SourcePath = Resolve-Path -Path $SourcePath -ErrorAction Stop
24+
$OutputPath = if (-not (Resolve-Path -Path $OutputPath -ErrorAction SilentlyContinue))
25+
{
26+
(New-Item -Path $OutputPath -ItemType Directory -Force).FullName
27+
}
28+
else
29+
{
30+
Resolve-Path -Path $OutputPath
31+
}
32+
33+
$rsopPath = Join-Path -Path $OutputPath -ChildPath rsop
34+
$policyPath = Join-Path -Path $OutputPath -ChildPath policies
35+
if (-not (Test-Path -Path $rsopPath))
36+
{
37+
$null = New-Item -Path $rsopPath -ItemType Directory -Force
38+
}
39+
40+
if (-not (Test-Path -Path $policyPath))
41+
{
42+
$null = New-Item -Path $policyPath -ItemType Directory -Force
43+
}
44+
45+
if (Get-DatumRsopCache)
46+
{
47+
Clear-DatumRsopCache
48+
}
49+
50+
$datum = New-DatumStructure -DefinitionFile (Join-Path $SourcePath Datum.yml)
51+
$rsops = Get-DatumRsop $datum (Get-DatumNodesRecursive -AllDatumNodes $Datum.AllNodes)
52+
$rsops | Export-AlfXml -Path $policyPath
53+
54+
if (-not $IncludeRsop)
55+
{
56+
$env:PSModulePath = $modOld
57+
return
58+
}
59+
60+
foreach ($rsop in $rsops)
61+
{
62+
$domainPath = Join-Path -Path $rsopPath -ChildPath $rsop.Domain
63+
if (-not (Test-Path -Path $domainPath))
64+
{
65+
$null = New-Item -Path $domainPath -ItemType Directory -Force
66+
}
67+
$rsop | ConvertTo-Yaml -OutFile (Join-Path -Path $domainPath -ChildPath "$($rsop.PolicyName).yml") -Force
68+
}
69+
70+
$env:PSModulePath = $modOld
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
param
2+
(
3+
[string]
4+
$DependencyPath = (Resolve-Path "$PSScriptRoot\requiredModules.psd1").Path,
5+
6+
[switch]
7+
$BuildWorker
8+
)
9+
10+
$psdependConfig = Import-PowerShellDataFile -Path $DependencyPath
11+
12+
if ($BuildWorker.IsPresent)
13+
{
14+
$null = Get-PackageProvider -Name NuGet -ForceBootstrap
15+
16+
Install-Module -Force -Name PackageManagement, PowerShellGet -Repository $psdependConfig.PSDependOptions.Parameters.Repository -Scope CurrentUser
17+
18+
Remove-Module -Name PowerShellGet -ErrorAction SilentlyContinue -Force
19+
Remove-Module -Name PackageManagement -ErrorAction SilentlyContinue -Force
20+
Import-Module -Force -Name PowerShellGet
21+
Import-Module -Force -Name PackageManagement
22+
23+
$null = Install-WindowsFeature -Name GPMC
24+
}
25+
26+
Save-Module -Name PSDepend -Repository $psdependConfig.PSDependOptions.Parameters.Repository -Path $psdependConfig.PSDependOptions.Target -Force
27+
Import-Module -Name (Join-Path -Path $psdependConfig.PSDependOptions.Target -ChildPath PSDepend\*\PSDepend.psd1 -Resolve)
28+
Invoke-PSDepend -Path $DependencyPath -Force
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
param
2+
(
3+
[string]
4+
$DependencyPath = (Resolve-Path "$PSScriptRoot\requiredModules.psd1").Path,
5+
6+
[string]
7+
$OutputPath = (Resolve-Path "$PSScriptRoot\..\output").Path,
8+
9+
[string]
10+
$SourcePath = "$PSScriptRoot\..\configurationdata"
11+
)
12+
13+
$psdependConfig = Import-PowerShellDataFile -Path $DependencyPath
14+
$modPath = Resolve-Path -Path $psdependConfig.PSDependOptions.Target
15+
$modOld = $env:PSModulePath
16+
$pathSeparator = [System.IO.Path]::PathSeparator
17+
$env:PSModulePath = "$modPath$pathSeparator$modOld"
18+
$datum = New-DatumStructure -DefinitionFile (Join-Path $SourcePath Datum.yml)
19+
[hashtable[]] $rsops = Get-DatumRsop $datum (Get-DatumNodesRecursive -AllDatumNodes $Datum.AllNodes)
20+
21+
foreach ($policy in (Get-ChildItem -Path (Join-Path -Path $OutputPath -ChildPath Policies) -Recurse -Filter *.xml))
22+
{
23+
$searcher = [adsisearcher]::new()
24+
$searcher.Filter = "(&(objectClass=groupPolicyContainer)(displayName=$($policy.BaseName)))"
25+
$policyFound = $searcher.FindOne()
26+
27+
if (-not $policyFound)
28+
{
29+
$null = New-GPO -Name $policy.BaseName -Comment "Auto-updated applocker policy" -Domain $policy.Directory.Name
30+
}
31+
32+
$rsop = $rsops | Where-Object { $_['PolicyName'] -eq $policy.BaseName }
33+
foreach ($link in $rsop.Links)
34+
{
35+
$param = @{
36+
Name = $rsop.PolicyName
37+
Target = $link.OrgUnitDn
38+
Domain = $policy.Directory.Name
39+
Confirm = $false
40+
}
41+
42+
if ($rsop.ContainsKey('Enabled'))
43+
{
44+
$param['LinkEnabled'] = $link.Enabled
45+
}
46+
if ($rsop.ContainsKey('Enforced'))
47+
{
48+
$param['Enforced'] = $link.Enforced
49+
}
50+
if ($rsop.ContainsKey('Order'))
51+
{
52+
$param['Order'] = $link.Order
53+
}
54+
55+
Set-GPLink @param
56+
}
57+
58+
$policyFound = $searcher.FindOne()
59+
60+
Set-AppLockerPolicy -XmlPolicy $policy.FullName -Ldap $policyFound.Path
61+
}
62+
63+
$env:PSModulePath = $modOld
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@{
2+
PSDependOptions = @{
3+
AddToPath = $false
4+
Target = 'output\RequiredModules'
5+
Parameters = @{
6+
Repository = 'PSGallery'
7+
AllowPreRelease = $true
8+
}
9+
}
10+
11+
'powershell-yaml' = '0.4.7'
12+
PSScriptAnalyzer = '1.21.0'
13+
Pester = '5.4.1'
14+
'Sampler.DscPipeline' = '0.2.0-preview0015' # Unfortunately still in preview
15+
Datum = '0.40.1'
16+
'Datum.InvokeCommand' = '0.3.0'
17+
AppLockerFoundry = '1.1.5'
18+
}

0 commit comments

Comments
 (0)