13 Commits

Author SHA1 Message Date
a57c64a04a Fix plugin version constraint
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-04 22:39:07 +02:00
d3802bba75 Remove redundant feedback 2021-06-04 22:35:56 +02:00
ae98042e4e Housekeeping;Add debugging information
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-04 22:31:53 +02:00
f36f452a59 Remove redundant variable;Fix path
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-04 22:17:55 +02:00
b0615f11d1 Migrate to HCL;Add packer init step;Add variable definitions
Some checks failed
continuous-integration/drone/push Build is failing
2021-06-04 22:16:06 +02:00
483013270d Allow multiple OU's for Delegation of Control
All checks were successful
continuous-integration/drone/push Build is passing
2021-05-03 14:18:58 +02:00
aa2c05df3f Fix yamllint errors #2
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-09 11:25:36 +02:00
280d3e2258 Fix yamllint errors;change yamllint config
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-09 11:24:46 +02:00
632caa89ef Switch yamllint configuration to 'relaxed'
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-09 11:03:40 +02:00
c04081bac1 Add image pull policy
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-09 10:59:46 +02:00
ae1a263129 Add yaml linting step
Some checks failed
continuous-integration/drone/push Build is failing
2021-04-09 10:56:48 +02:00
f8a8cb80c8 Separate firewall configuration between linked OUs
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-08 17:13:24 +02:00
ed69de5d27 Add errorhandling;Fix OU
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-27 08:56:26 +01:00
21 changed files with 457 additions and 253 deletions

View File

@ -3,24 +3,35 @@ type: kubernetes
name: 'Packer Build'
steps:
- name: Active Directory Domain Services
- name: Debugging information
image: bv11-cr01.bessems.eu/library/packer-extended
commands:
- yamllint --version
- packer --version
- pwsh --version
- ovftool --version
- name: Active Directory Domain Services
image: bv11-cr01.bessems.eu/library/packer-extended
pull: always
commands:
- |
yamllint -d "{extends: relaxed, rules: {line-length: disable}}" scripts
- |
packer init -upgrade \
./packer
- |
packer validate \
-var-file=packer/variables.vsphere.json \
-var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \
-var vsphere_password=$${VSPHERE_PASSWORD} \
-var winrm_password=$${WINRM_PASSWORD} \
packer/adds.json
./packer
- |
packer build \
-on-error=cleanup \
-var-file=packer/variables.vsphere.json \
-on-error=cleanup -timestamp-ui \
-var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \
-var vsphere_password=$${VSPHERE_PASSWORD} \
-var winrm_password=$${WINRM_PASSWORD} \
packer/adds.json
./packer
environment:
VSPHERE_PASSWORD:
from_secret: vsphere_password

View File

@ -1,91 +0,0 @@
{
"builders": [
{
"type": "vsphere-clone",
"name": "adds",
"vcenter_server": "{{user `vcenter_server`}}",
"username": "{{user `vsphere_username`}}",
"password": "{{user `vsphere_password`}}",
"insecure_connection": "true",
"vm_name": "adds-{{user `vm_name`}}",
"datastore": "{{user `vsphere_datastore`}}",
"folder": "{{user `vsphere_folder`}}",
"datacenter": "{{user `vsphere_datacenter`}}",
"host": "{{user `vsphere_host`}}",
"boot_order": "disk,cdrom",
"communicator": "winrm",
"winrm_username": "administrator",
"winrm_password": "{{user `winrm_password`}}",
"winrm_timeout": "10m",
"cpus": 2,
"RAM": 8192,
"template": "Windows-Server-2019-LTSC",
"floppy_files": [
"packer/preseed/ADDS/Sysprep_Unattend.xml"
],
"boot_command": "",
"boot_wait": "2m30s",
"shutdown_command": "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml",
"shutdown_timeout": "1h",
"export": {
"images": false
}
}
],
"provisioners": [
{
"type": "powershell",
"inline": [
"New-Item -Path 'C:\\Payload\\Scripts' -ItemType 'Directory' -Force:$True -Confirm:$False"
]
},
{
"type": "file",
"source": "scripts/ADDS/payload/",
"destination": "C:\\Payload\\"
},
{
"type": "powershell",
"scripts": [
"scripts/ADDS/Install-Prerequisites.ps1",
"scripts/ADDS/Register-ScheduledTask.ps1"
]
}
],
"post-processors": [[
{
"type": "shell-local",
"inline": [
"pwsh -command \"& scripts/Update-OvfConfiguration.ps1 \\",
" -OVFFile './output-adds/adds-{{user `vm_name`}}.ovf' \\",
" -Parameter @{'appliance.name'='ADDS';'appliance.version'='{{user `vm_name`}}'}\"",
"pwsh -file scripts/Update-Manifest.ps1 \\",
" -ManifestFileName './output-adds/adds-{{user `vm_name`}}.mf'",
"ovftool --acceptAllEulas --allowExtraConfig --overwrite \\",
" './output-adds/adds-{{user `vm_name`}}.ovf' \\",
" /output/ADDS-appliance.ova"
]
}
],
[
{
"type": "shell-local",
"inline": [
"pwsh -file scripts/Remove-Resources.ps1 \\",
" -VMName 'adds-{{user `vm_name`}}' \\",
" -VSphereFQDN '{{user `vcenter_server`}}' \\",
" -VSphereUsername '{{user `vsphere_username`}}' \\",
" -VSpherePassword '{{user `vsphere_password`}}'"
]
}
]]
}

90
packer/adds.pkr.hcl Normal file
View File

@ -0,0 +1,90 @@
packer {
required_plugins {
windows-update = {
version = ">= 0.12.0"
source = "github.com/rgl/windows-update"
}
}
}
source "vsphere-clone" "adds" {
vcenter_server = var.vcenter_server
username = var.vsphere_username
password = var.vsphere_password
insecure_connection = "true"
vm_name = "adds-${var.vm_name}"
datacenter = var.vsphere_datacenter
host = var.vsphere_host
folder = var.vsphere_folder
datastore = var.vsphere_datastore
template = "Windows-Server-2019-LTSC"
boot_order = "disk,cdrom"
boot_command = [""]
boot_wait = "2m30s"
communicator = "winrm"
winrm_password = var.winrm_password
winrm_timeout = "10m"
winrm_username = "administrator"
RAM = 8192
CPUs = 2
floppy_files = [
"packer/preseed/ADDS/Sysprep_Unattend.xml"
]
shutdown_command = "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml"
shutdown_timeout = "1h"
export {
images = false
}
}
build {
sources = ["source.vsphere-clone.adds"]
provisioner "powershell" {
inline = [
"New-Item -Path 'C:\\Payload\\Scripts' -ItemType 'Directory' -Force:$True -Confirm:$False"
]
}
provisioner "file" {
destination = "C:\\Payload\\"
source = "scripts/ADDS/payload/"
}
provisioner "powershell" {
scripts = [
"scripts/ADDS/Install-Prerequisites.ps1",
"scripts/ADDS/Register-ScheduledTask.ps1"
]
}
post-processor "shell-local" {
inline = [
"pwsh -command \"& scripts/Update-OvfConfiguration.ps1 \\",
" -OVFFile './output-adds/adds-${var.vm_name}.ovf' \\",
" -Parameter @{'appliance.name'='ADDS';'appliance.version'='${var.vm_name}'}\"",
"pwsh -file scripts/Update-Manifest.ps1 \\",
" -ManifestFileName './output-adds/adds-${var.vm_name}.mf'",
"ovftool --acceptAllEulas --allowExtraConfig --overwrite \\",
" './output-adds/adds-${var.vm_name}.ovf' \\",
" /output/ADDS-appliance.ova"
]
}
post-processor "shell-local" {
inline = [
"pwsh -file scripts/Remove-Resources.ps1 \\",
" -VMName 'adds-${var.vm_name}' \\",
" -VSphereFQDN '${var.vcenter_server}' \\",
" -VSphereUsername '${var.vsphere_username}' \\",
" -VSpherePassword '${var.vsphere_password}'"
]
}
}

14
packer/variables.pkr.hcl Normal file
View File

@ -0,0 +1,14 @@
variable "vcenter_server" {}
variable "vsphere_username" {}
variable "vsphere_password" {}
variable "vsphere_host" {}
variable "vsphere_datacenter" {}
variable "vsphere_templatefolder" {}
variable "vsphere_folder" {}
variable "vsphere_datastore" {}
variable "vsphere_network" {}
variable "vm_name" {}
variable "winrm_password" {}

View File

@ -1,11 +0,0 @@
{
"vcenter_server": "bv11-vc.bessems.lan",
"vsphere_username": "administrator@vsphere.local",
"vsphere_datacenter": "DeSchakel",
"vsphere_host": "bv11-esx.bessems.lan",
"vsphere_hostip": "192.168.11.200",
"vsphere_datastore": "Datastore02.SSD",
"vsphere_folder": "/Packer",
"vsphere_templatefolder": "/Templates",
"vsphere_network": "LAN"
}

View File

@ -0,0 +1,8 @@
vcenter_server = "bv11-vc.bessems.lan"
vsphere_username = "administrator@vsphere.local"
vsphere_datacenter = "DeSchakel"
vsphere_host = "bv11-esx.bessems.lan"
vsphere_datastore = "Datastore01.SSD"
vsphere_folder = "/Packer"
vsphere_templatefolder = "/Templates"
vsphere_network = "LAN"

View File

@ -7,6 +7,8 @@ OrganizationalUnits:
Description: ''
- DistinguishedName: OU=Laptops,OU=Clients,OU=Computer accounts
Description: ''
- DistinguishedName: OU=Kiosks,OU=Clients,OU=Computer accounts
Description: ''
- DistinguishedName: OU=Servers,OU=Computer accounts
Description: ''

View File

@ -11,7 +11,6 @@ Users:
- DistinguishedName: CN=zzLDAP,OU=Service accounts,OU=Privileged,OU=User accounts
Password: "{{ password.zzldap }}"
MemberOf: []
---
Variables:
- Name: password.janedoe

View File

@ -65,52 +65,61 @@ If (@('primary','standalone') -contains $Parameter['deployment.type']) {
$GUIDMap['null'] = [Guid]::Empty
ForEach ($Entry in $Delegations.DelegationEntries) {
$GetADObjectSplat = @{
Identity = $Entry.OrganizationalUnit + (($Parameter['addsconfig.domainname'] -split '\.' | ForEach-Object {',DC={0}' -f $_}) -join '')
}
$OU = Get-ADObject @GetADObjectSplat
$GetACLSPlat = @{
Path = "$($PSDrive.Name):\$($OU.DistinguishedName)"
}
$ACL = Get-ACL @GetACLSPlat
$GetADObjectSplat = @{
Filter = "sAMAccountName -eq '$($Entry.Principal)'"
Properties = 'objectSID'
}
$Principal = Get-ADObject @GetADObjectSplat
ForEach ($Rule in $Entry.AccessRules) {
If ($Rule.ObjectType -eq '') {
$Rule.ObjectType = 'null'
ForEach ($OU in $Entry.OrganizationalUnit) {
$GetADObjectSplat = @{
Identity = ($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))
ErrorAction = 'SilentlyContinue'
}
If ($Rule.InheritedObjectType -eq '') {
$Rule.InheritedObjectType = 'null'
$OU = Get-ADObject @GetADObjectSplat
If ([boolean]$OU) {
$GetACLSPlat = @{
Path = "$($PSDrive.Name):\$($OU.DistinguishedName)"
}
$ACL = Get-ACL @GetACLSPlat
}
Else {
# Respective OU was not found in Active Directory; skipping permission assignment
Continue
}
$NewACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
# An IdentityReference object that identifies the trustee of the access rule.
[System.Security.Principal.IdentityReference]$Principal.objectSID,
# A combination of one or more of the ActiveDirectoryRights enumeration values that specifies the rights of the access rule.
[System.DirectoryServices.ActiveDirectoryRights]$Rule.ActiveDirectoryRights,
# One of the AccessControlType enumeration values that specifies the access rule type.
[System.Security.AccessControl.AccessControlType]$Rule.AccessControlType,
# The schema GUID of the object to which the access rule applies.
[Guid]$GUIDMap[$Rule.ObjectType],
# One of the ActiveDirectorySecurityInheritance enumeration values that specifies the inheritance type of the access rule.
[System.DirectoryServices.ActiveDirectorySecurityInheritance]$Rule.ActiveDirectorySecurityInheritance,
# The schema GUID of the child object type that can inherit this access rule.
[Guid]$GUIDMap[$Rule.InheritedObjectType]
)
$ACL.AddAccessRule($NewACE)
}
ForEach ($Rule in $Entry.AccessRules) {
If ($Rule.ObjectType -eq '') {
$Rule.ObjectType = 'null'
}
If ($Rule.InheritedObjectType -eq '') {
$Rule.InheritedObjectType = 'null'
}
$NewACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
# An IdentityReference object that identifies the trustee of the access rule.
[System.Security.Principal.IdentityReference]$Principal.objectSID,
# A combination of one or more of the ActiveDirectoryRights enumeration values that specifies the rights of the access rule.
[System.DirectoryServices.ActiveDirectoryRights]$Rule.ActiveDirectoryRights,
# One of the AccessControlType enumeration values that specifies the access rule type.
[System.Security.AccessControl.AccessControlType]$Rule.AccessControlType,
# The schema GUID of the object to which the access rule applies.
[Guid]$GUIDMap[$Rule.ObjectType],
# One of the ActiveDirectorySecurityInheritance enumeration values that specifies the inheritance type of the access rule.
[System.DirectoryServices.ActiveDirectorySecurityInheritance]$Rule.ActiveDirectorySecurityInheritance,
# The schema GUID of the child object type that can inherit this access rule.
[Guid]$GUIDMap[$Rule.InheritedObjectType]
)
$ACL.AddAccessRule($NewACE)
}
$SetAclSplat = @{
Path = "$($PSDrive.Name):\$($OU.DistinguishedName)"
AclObject = $ACL
ErrorAction = 'Continue'
$SetAclSplat = @{
Path = "$($PSDrive.Name):\$($OU.DistinguishedName)"
AclObject = $ACL
ErrorAction = 'Continue'
}
Set-Acl @SetAclSplat
}
Set-Acl @SetAclSplat
}
If ([boolean]($PSDrive.Name -eq 'ADDS') -eq $True) {

View File

@ -1,6 +1,8 @@
DelegationEntries:
- Principal: admJaneD
OrganizationalUnit: CN=Computers # Entries will be concatenated with ',DC=<example>,DC=<org>' automatically
- Principal: admJaneD # Entries will be concatenated with ',DC=<example>,DC=<org>' automatically
OrganizationalUnit:
- CN=Computers
- OU=Kiosks,OU=Clients,OU=Computer accounts
AccessRules:
- ActiveDirectoryRights: Self # A combination of one or more of the ActiveDirectoryRights enumeration values that specifies the rights of the access rule.
AccessControlType: Allow # One of the AccessControlType enumeration values that specifies the access rule type.
@ -48,7 +50,8 @@ DelegationEntries:
ObjectType: Computer
InheritedObjectType: ''
- Principal: admJaneD
OrganizationalUnit: OU=Clients,OU=Computer accounts
OrganizationalUnit:
- OU=Clients,OU=Computer accounts
AccessRules:
- ActiveDirectoryRights: CreateChild, DeleteChild
AccessControlType: Allow

View File

@ -1,3 +1,6 @@
Name: 'COMP: Firewall (Clients)'
LinkedOUs:
- OU=Clients,OU=Computer accounts
FirewallRules:
- Description: Rule A
Action: Block
@ -59,4 +62,4 @@ FirewallProfiles:
# Variables:
# - Name: foo
# Expression: |
# Write-Host 'bar'
# Write-Host 'bar'

View File

@ -0,0 +1,65 @@
Name: 'COMP: Firewall (DomainControllers)'
LinkedOUs:
- OU=Domain Controllers
FirewallRules:
- Description: Rule A
Action: Block
Direction: Inbound
Program: ''
Port: '21-22,25'
Protocol: TCP
- Description: Rule B
Action: Allow
Direction: Inbound
Program: D:\MSSQL\sqlsvr.exe
Port: ''
Protocol: ''
FirewallProfiles:
- Name: Domain
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\domainfw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
- Name: Private
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\privatefw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
- Name: Public
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\publicfw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
# ---
# Variables:
# - Name: foo
# Expression: |
# Write-Host 'bar'

View File

@ -6,104 +6,135 @@ Param(
# Only executed on primary or standalone Domain Controller
If (@('primary','standalone') -contains $Parameter['deployment.type']) {
$GetContentSplat = @{
$GetItemSplat = @{
Path = "$($PSScriptRoot)\$($MyInvocation.MyCommand)".Replace('.ps1', '.yml')
Raw = $true
}
$RawContent = Get-Content @GetContentSplat
$ConvertFromYamlSplat = @{
Yaml = $RawContent
AllDocuments = $True
}
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
# Check if the respective .yml file declared substitutions which need to be parsed
If (($YamlDocuments.Count -gt 1) -and $YamlDocuments[-1].Variables) {
ForEach ($Pattern in $YamlDocuments[-1].Variables) {
$RawContent = $RawContent -replace "\{\{ ($($Pattern.Name)) \}\}", [string](Invoke-Expression -Command $Pattern.Expression)
ForEach ($File in (Get-Item @GetItemSplat)) {
Try {
Write-Host "Loading/parsing file '$($File)' ..."
$GetContentSplat = @{
Path = $File
Raw = $True
}
$RawContent = Get-Content @GetContentSplat
$ConvertFromYamlSplat = @{
Yaml = $RawContent
AllDocuments = $True
}
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
}
# Perform conversion to Yaml again, now with parsed file contents
$ConvertFromYamlSplat = @{
Yaml = $RawContent
AllDocuments = $True
Catch {
$ParseErrors += "While processing '$($File)': $($_.Exception.Message)"
Continue
}
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
$Settings = $YamlDocuments[0..($YamlDocuments.Count - 2)]
}
Else {
$Settings = $YamlDocuments
}
# Check if the respective .yml file declared substitutions which need to be parsed
If (($YamlDocuments.Count -gt 1) -and $YamlDocuments[-1].Variables) {
Try {
ForEach ($Pattern in $YamlDocuments[-1].Variables) {
$RawContent = $RawContent -replace "\{\{ ($($Pattern.Name)) \}\}", [string](Invoke-Expression -Command $Pattern.Expression)
}
# Perform conversion to Yaml again, now with parsed file contents
$ConvertFromYamlSplat = @{
Yaml = $RawContent
AllDocuments = $True
}
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
}
Catch {
$ParseErrors += "While processing '$($File)' (after substitutions): $($_.Exception.Message)"
Continue
}
$NewGPOSplat = @{
Name = 'COMP: Firewall (Servers)'
}
$NewGPO = New-GPO @NewGPOSplat
$OpenNetGPOSplat = @{
PolicyStore = "$($Parameter['addsconfig.domainname'])\$($NewGPO.DisplayName)"
}
$GPOSession = Open-NetGPO @OpenNetGPOSplat
ForEach ($Rule in $Settings.FirewallRules) {
$NewNetFirewallRuleSplat = @{
# Using so-called string formatting with the '-f' operator (looks more complicated than it is) to create consistent policy names:
# Examples:
# 'DENY: Inbound port 443 (TCP)'
# 'ALLOW: Inbound 'D:\MSSQL\bin\sqlservr.exe'
DisplayName = ("{0}: {1} {2} {3} {4}" -f
$Rule.Action.ToUpper(),
$Rule.Direction,
("'$($Rule.Program)'", $NULL)[!($Rule.Program)],
("Port $($Rule.Port)", $NULL)[!($Rule.Port)],
("($($Rule.Protocol))", $NULL)[!($Rule.Protocol)]
) -replace '\s+',' '
Description = $Rule.Description
Action = $Rule.Action
Direction = $Rule.Direction
Program = ($Rule.Program, 'Any')[!($Rule.Program)]
LocalPort = ($Rule.Port.Split(','), 'Any')[!($Rule.Port)]
Protocol = ($Rule.Protocol, 'Any')[!($Rule.Protocol)]
GPOSession = $GPOSession
PolicyStore = $NewGPO.DisplayName
Confirm = $False
$Settings = $YamlDocuments[0..($YamlDocuments.Count - 2)]
}
New-NetFirewallRule @NewNetFirewallRuleSplat
}
ForEach ($Profile in $Settings.FirewallProfiles) {
$SetNetFirewallProfileSplat = @{
Name = $Profile.Name
Enabled = $Profile.Enabled
DefaultInboundAction = $Profile.Connections.Inbound
DefaultOutboundAction = $Profile.Connections.Outbound
LogAllowed = $Profile.Logging.LogSuccessfullConnections
LogBlocked = $Profile.Logging.LogDroppedPackets
LogFileName = $Profile.Logging.Name
LogMaxSizeKilobytes = $Profile.Logging.SizeLimit
AllowLocalFirewallRules = $Profile.Settings.ApplyLocalFirewallRules
AllowLocalIPsecRules = $Profile.Settings.ApplyLocalConnectionSecurityRules
NotifyOnListen = $Profile.Settings.DisplayNotification
GPOSession = $GPOSession
PolicyStore = $NewGPO.DisplayName
Confirm = $False
Else {
$Settings = $YamlDocuments
}
$NewGPOSplat = @{
Name = $Settings.Name
}
$NewGPO = New-GPO @NewGPOSplat
$OpenNetGPOSplat = @{
PolicyStore = "$($Parameter['addsconfig.domainname'])\$($NewGPO.DisplayName)"
}
$GPOSession = Open-NetGPO @OpenNetGPOSplat
ForEach ($Rule in $Settings.FirewallRules) {
$NewNetFirewallRuleSplat = @{
# Using so-called string formatting with the '-f' operator (looks more complicated than it is) to create consistent policy names:
# Examples:
# 'DENY: Inbound port 443 (TCP)'
# 'ALLOW: Inbound 'D:\MSSQL\bin\sqlservr.exe'
DisplayName = ("{0}: {1} {2} {3} {4}" -f
$Rule.Action.ToUpper(),
$Rule.Direction,
("'$($Rule.Program)'", $NULL)[!($Rule.Program)],
("Port $($Rule.Port)", $NULL)[!($Rule.Port)],
("($($Rule.Protocol))", $NULL)[!($Rule.Protocol)]
) -replace '\s+',' '
Description = $Rule.Description
Action = $Rule.Action
Direction = $Rule.Direction
Program = ($Rule.Program, 'Any')[!($Rule.Program)]
LocalPort = ($Rule.Port.Split(','), 'Any')[!($Rule.Port)]
Protocol = ($Rule.Protocol, 'Any')[!($Rule.Protocol)]
GPOSession = $GPOSession
PolicyStore = $NewGPO.DisplayName
Confirm = $False
}
New-NetFirewallRule @NewNetFirewallRuleSplat
}
ForEach ($Profile in $Settings.FirewallProfiles) {
$SetNetFirewallProfileSplat = @{
Name = $Profile.Name
Enabled = $Profile.Enabled
DefaultInboundAction = $Profile.Connections.Inbound
DefaultOutboundAction = $Profile.Connections.Outbound
LogAllowed = $Profile.Logging.LogSuccessfullConnections
LogBlocked = $Profile.Logging.LogDroppedPackets
LogFileName = $Profile.Logging.Name
LogMaxSizeKilobytes = $Profile.Logging.SizeLimit
AllowLocalFirewallRules = $Profile.Settings.ApplyLocalFirewallRules
AllowLocalIPsecRules = $Profile.Settings.ApplyLocalConnectionSecurityRules
NotifyOnListen = $Profile.Settings.DisplayNotification
GPOSession = $GPOSession
PolicyStore = $NewGPO.DisplayName
Confirm = $False
}
Set-NetFirewallProfile @SetNetFirewallProfileSplat
}
$SaveNetGPOSplat = @{
GPOSession = $GPOSession
}
Save-NetGPO @SaveNetGPOSplat
ForEach ($OU in $Settings.LinkedOUs) {
If (Test-Path "AD:\$($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))") {
Try {
Write-Host "Linking policy '$($NewGPO.DisplayName)' to OU '$($OU)' ..."
$NewGPLinkSplat = @{
Name = $NewGPO.DisplayName
Target = $OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext)
}
New-GPLink @NewGPLinkSplat | Out-Null
}
Catch {
$ParseErrors += "Could not link GPO '$($NewGPO.DisplayName)' to OU '$($OU)'"
Continue
}
}
Else {
$ParseErrors += "Path not accessible (referred to by '$($NewGPO.DisplayName)'): 'AD:\$($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))'"
Continue
}
}
Set-NetFirewallProfile @SetNetFirewallProfileSplat
}
$SaveNetGPOSplat = @{
GPOSession = $GPOSession
If ($ParseErrors) {
Throw "One or more errors occurred:`n$($ParseErrors -join "`n")"
}
Save-NetGPO @SaveNetGPOSplat
$NewGPLinkSplat = @{
Name = $NewGPO.DisplayName
# Should probably be configurable through yml
Target = 'OU=Servers,OU=Computer accounts,DC=' + $Parameter['addsconfig.domainname'].Replace('.', ',DC=')
}
New-GPLink @NewGPLinkSplat
$NewGPLinkSplat = @{
Name = $NewGPO.DisplayName
Target = 'OU=Domain Controllers,DC=' + $Parameter['addsconfig.domainname'].Replace('.', ',DC=')
}
New-GPLink @NewGPLinkSplat
}

View File

@ -0,0 +1,65 @@
Name: 'COMP: Firewall (Servers)'
LinkedOUs:
- OU=Servers,OU=Computer accounts
FirewallRules:
- Description: Rule A
Action: Block
Direction: Inbound
Program: ''
Port: '21-22,25'
Protocol: TCP
- Description: Rule B
Action: Allow
Direction: Inbound
Program: D:\MSSQL\sqlsvr.exe
Port: ''
Protocol: ''
FirewallProfiles:
- Name: Domain
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\domainfw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
- Name: Private
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\privatefw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
- Name: Public
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\publicfw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
# ---
# Variables:
# - Name: foo
# Expression: |
# Write-Host 'bar'

View File

@ -24,4 +24,4 @@ Variables:
(Resolve-DnsName -Name $Parameter['addsconfig.domainname'] | Sort-Object)[0].IPAddress
- Name: secondarydc
Expression: |
(Resolve-DnsName -Name $Parameter['addsconfig.domainname'] | Sort-Object)[1].IPAddress
(Resolve-DnsName -Name $Parameter['addsconfig.domainname'] | Sort-Object)[1].IPAddress

View File

@ -6,4 +6,4 @@
# Variables:
# - Name: foo
# Expression: |
# Write-Host 'bar'
# Write-Host 'bar'

View File

@ -16,4 +16,4 @@ RegistryEntries:
- Key: HKLM\Software\Policies\Microsoft\Windows\System
Type: Dword
ValueName: UserPolicyMode
Value: 2
Value: 2

View File

@ -33,4 +33,4 @@ RegistryEntries:
Variables:
- Name: addsconfig.ntpserver
Expression: |
($Parameter['addsconfig.ntpserver'] -split ',' | ForEach-Object {'{0},0x1' -f $_}) -join ' '
($Parameter['addsconfig.ntpserver'] -split ',' | ForEach-Object {'{0},0x1' -f $_}) -join ' '

View File

@ -1,7 +1,7 @@
Name: 'COMP: Restrict Internet Communication'
Type: Object
LinkedOUs:
- OU=Servers
- OU=Servers,OU=Computer accounts
WMIFilters: []
RegistryEntries:
- Key: HKLM\Software\Policies\Microsoft\InternetManagement
@ -113,4 +113,4 @@ RegistryEntries:
- Key: HKLM\Software\Policies\Microsoft\WindowsMovieMaker
Type: DWord
ValueName: WebPublish
Value: 1
Value: 1

View File

@ -175,16 +175,22 @@ If (@('primary','standalone') -contains $Parameter['deployment.type']) {
ForEach ($OU in $GroupPolicy.LinkedOUs) {
If (Test-Path "AD:\$($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))") {
Write-Host "Linking policy '$($NewGPO.DisplayName)' to OU '$($OU)' ..."
$NewGPLinkSplat = @{
Name = $NewGPO.DisplayName
Target = $OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext)
# ErrorAction = 'SilentlyContinue'
Try {
Write-Host "Linking policy '$($NewGPO.DisplayName)' to OU '$($OU)' ..."
$NewGPLinkSplat = @{
Name = $NewGPO.DisplayName
Target = $OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext)
}
New-GPLink @NewGPLinkSplat | Out-Null
}
Catch {
$ParseErrors += "Could not link GPO '$($NewGPO.DisplayName)' to OU '$($OU)'"
Continue
}
New-GPLink @NewGPLinkSplat | Out-Null
}
Else {
Throw "Path not accessible: 'AD:\$($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))"
$ParseErrors += "Path not accessible (referred to by '$($NewGPO.DisplayName)'): 'AD:\$($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))'"
Continue
}
}
}

View File

@ -11,4 +11,4 @@ Password:
Length:
Minimum: 10
History: 0
ReversibleEncryption: False
ReversibleEncryption: False