From 4c99fd9d300f76487c7cf6f2c257c0cf542868f4 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Thu, 29 Feb 2024 16:42:15 +0000 Subject: [PATCH 01/24] add module files --- powershell/Modules/ModPlatformAD/ModPlatformADGPO.psm1 | 0 powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 powershell/Modules/ModPlatformAD/ModPlatformADGPO.psm1 create mode 100644 powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADGPO.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADGPO.psm1 new file mode 100644 index 000000000..e69de29bb diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 new file mode 100644 index 000000000..e69de29bb From 4c3288f18a8e2159b3a731df8f5e87f8fa6d1204 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Mar 2024 13:58:12 +0000 Subject: [PATCH 02/24] add domain --- .../ModPlatformAD/ModPlatformADDomain.psm1 | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 new file mode 100644 index 000000000..4698607a3 --- /dev/null +++ b/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 @@ -0,0 +1,35 @@ +function Install-ModPlatformADDomain { + +<# +.SYNOPSIS + Installs the Active Directory Domain Services Windows Feature and Domain + +.DESCRIPTION + TODO: Add this and Parameters + +.PARAMETER DomainName + Domain Name to create + +.EXAMPLE + Install-ModPlatformADDomain -DomainName "test.loc" + +.OUTPUTS + PSCredentialObject +#> + +[CmdletBinding()] +param ( + [Parameter(Mandatory=$true)][string]$DomainName +) + + $ErrorActionPreference = "Stop" + + Install-WindowsFeature AD-Domain-Services -IncludeManagementTools + + # Get SafeModeAdministratorPassword from secrets of call ADCredential? + + Install-ADDSForest -DomainName $DomainName -InstallDNS -CreateDnsDelegation:$false -DatabasePath "C:\Windows\NTDS" -LogPath "C:\Windows\NTDS" -SYSVOLPath "C:\Windows\SYSVOL" -Force -SafeModeAdministratorPassword (ConvertTo-SecureString $SafeModeAdministratorPassword -AsPlainText -Force) + +} + +Export-ModuleMember -Function Install-ModPlatformADDomain \ No newline at end of file From b2e87f9f82df884b757e8f5a01d9ca58d67b589b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Mar 2024 15:00:08 +0000 Subject: [PATCH 03/24] add scripts and get secret --- powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 | 3 ++- powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 index 38fb45a68..c919e7fb4 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 @@ -68,7 +68,8 @@ PowerShellVersion = '4.0' # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess NestedModules = @('ModPlatformADComputer.psm1', 'ModPlatformADConfig.psm1', - 'ModPlatformADCredential.psm1') + 'ModPlatformADCredential.psm1', + 'ModPlatformADDomain.psm1') # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. FunctionsToExport = 'Rename-ModPlatformADComputer', 'Add-ModPlatformADComputer', diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 index 4698607a3..fbbab186e 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 @@ -26,7 +26,8 @@ param ( Install-WindowsFeature AD-Domain-Services -IncludeManagementTools - # Get SafeModeAdministratorPassword from secrets of call ADCredential? + # placeholder - may need to be replaced + $SafeModeAdministratorPassword = aws secretsmanager get-secret-value --secret-id devtestDomainPassword --query 'SecretString' --output text Install-ADDSForest -DomainName $DomainName -InstallDNS -CreateDnsDelegation:$false -DatabasePath "C:\Windows\NTDS" -LogPath "C:\Windows\NTDS" -SYSVOLPath "C:\Windows\SYSVOL" -Force -SafeModeAdministratorPassword (ConvertTo-SecureString $SafeModeAdministratorPassword -AsPlainText -Force) From 050d2ab7afde19d599dc2c79a0ab8689be91ab90 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Mar 2024 15:00:59 +0000 Subject: [PATCH 04/24] add script file --- .../ModPlatformAD/New-ModPlatformADDomain.ps1 | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 powershell/Scripts/ModPlatformAD/New-ModPlatformADDomain.ps1 diff --git a/powershell/Scripts/ModPlatformAD/New-ModPlatformADDomain.ps1 b/powershell/Scripts/ModPlatformAD/New-ModPlatformADDomain.ps1 new file mode 100644 index 000000000..38dae6782 --- /dev/null +++ b/powershell/Scripts/ModPlatformAD/New-ModPlatformADDomain.ps1 @@ -0,0 +1,21 @@ +<# +.SYNOPSIS + Create an Active Directory Domain Controller in Modernisation-Platform + +.DESCRIPTION + + +.PARAMETER DomainName + +.EXAMPLE + New-ModPlatformADDomain -DomainName "domain.name.root" +#> + +[CmdletBinding()] +param ( + [string]$DomainName = "test.loc" +) + +Import-Module ModPlatformAD -Force + +Install-ModPlatformADDomain -DomainName $DomainName \ No newline at end of file From 47cf7113951de9e3fde2daba856b503cae0c4c3d Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Mon, 4 Mar 2024 16:51:47 +0000 Subject: [PATCH 05/24] automatically create OU folder structure --- .../ModPlatformAD/ModPlatformADOU.psm1 | 56 +++++++++++++++++++ .../ModPlatformAD/Set-ModPlatformADOU.ps1 | 46 +++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index e69de29bb..90b962092 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -0,0 +1,56 @@ +function New-ADOrganizationalUnit { + +<# +.SYNOPSIS + Creates a New-ADOrganizationalUnit + +.DESCRIPTION + Using configuration returned from Get-ModPlatformADConfig, this function + optionally assumes a role to access a secret containing the password of the + domain join username. EC2 requires permissions to join the given role, + a SSM parameter containing account IDs, and the aws cli. + +.PARAMETER Name + Name of the Organizational Unit to create + +.PARAMETER Path + The path of the Organizational Unit to create + +.PARAMETER Description + Description of the Organizational Unit to create + +.PARAMETER ProtectedFromAccidentalDeletion + Whether the Organizational Unit should be protected from accidental deletion, defaults to false + +.EXAMPLE + New-ADOrganizationalUnit -Name "TestOU" -Path "OU=Test,DC=example,DC=com" -Description "Test OU" + +.OUTPUTS + PSCredentialObject +#> + + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string]$Name, + + [Parameter(Mandatory = $true)] + [string]$Path, + + [Parameter(Mandatory = $false)] + [string]$Description, + + [Parameter(Mandatory = $false)] + [bool]$ProtectedFromAccidentalDeletion = $false + ) + + $ou = Get-ADOrganizationalUnit -Filter "Name -eq '$Name'" -SearchBase $Path + if ($ou) { + Write-Host "Organizational Unit $Name already exists in $Path" -ForegroundColor Yellow + } else { + $ou = New-ADOrganizationalUnit -Name $Name -Path $Path -Description $Description -ProtectedFromAccidentalDeletion $ProtectedFromAccidentalDeletion + Write-Host "Organizational Unit $Name created in $Path" -ForegroundColor Green + } +} + +Export-ModuleMember -Function New-ADOrganizationalUnit diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 new file mode 100644 index 000000000..5f6d1a231 --- /dev/null +++ b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 @@ -0,0 +1,46 @@ +<# +.SYNOPSIS + Create an Active Directory Domain Controller in Modernisation-Platform + +.DESCRIPTION + + +.PARAMETER DomainName + +.EXAMPLE + New-ModPlatformADDomain -DomainName "domain.name.root" +#> + +[CmdletBinding()] +param ( + [string]$DomainName = "test.loc" +) + +Import-Module ModPlatformAD -Force + +$DomainNameString = ($DomainName -split "\." | ForEach-Object { "DC=$_" }) -join "," + +New-ADOrganizationalUnit -Name "ModPlatformComputers" -Path $DomainNameString -Description "Modernisation Platform Computers" -ProtectedFromAccidentalDeletion $true + +# set sub-level AD OU for Modernisation Platform Computers Environments +$topLevelOU = "OU=ModPlatformComputers" + +$repoOwner = "ministryofjustice" +$repoName = "modernisation-platform-environments" +$repoPAth = "terraform/environments" + +$environments = @("development", "test", "preproduction", "production") +$excludeTerraformEnvironments = @("example") + +$ApiUrl = "https://api.github.com/repos/$repoOwner/$repoName/contents/$repoPAth" + +$Response = Invoke-RestMethod -Uri $ApiUrl + +$Response | Where-Object { $_.type -eq "dir" -and $excludeTerraformEnvironments -notcontains $_.name } | ForEach-Object { $_.name } | ForEach-Object { + New-ADOrganizationalUnit -Name $_ -Path "$topLevelOU,$DomainNameString" -Description "Modernisation Platform Computers $_" -ProtectedFromAccidentalDeletion $true + + ForEach ($environment in $environments) { + New-ADOrganizationalUnit -Name $environment -Path "OU=$_,$topLevelOU,$DomainNameString" -Description "Modernisation Platform Computers $_ $environment" -ProtectedFromAccidentalDeletion $true + } +} + From 701cf24d7b837096aa40df90bd870aa754eaf780 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Wed, 6 Mar 2024 11:44:34 +0000 Subject: [PATCH 06/24] create config from yaml file --- powershell/Configs/ADConfigDevTest.yaml | 21 ++++++++ powershell/Configs/ADConfigProdPreProd.yaml | 22 +++++++++ .../ModPlatformAD/ModPlatformADOU.psm1 | 49 ++++++++++++++++++- .../ModPlatformAD/Set-ModPlatformADOU.ps1 | 10 ++-- .../Set-ModPlatformADOUStructure.ps1 | 48 ++++++++++++++++++ 5 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 powershell/Configs/ADConfigDevTest.yaml create mode 100644 powershell/Configs/ADConfigProdPreProd.yaml create mode 100644 powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 diff --git a/powershell/Configs/ADConfigDevTest.yaml b/powershell/Configs/ADConfigDevTest.yaml new file mode 100644 index 000000000..93bcfa841 --- /dev/null +++ b/powershell/Configs/ADConfigDevTest.yaml @@ -0,0 +1,21 @@ +ActiveDirectory: + DomainNameFQDN: "test.loc" + OUs: + - name: "ModPlatformComputers" + description: "Modernisation Platform Computers" + GPOs: + children: + - name: "corporate-staff-rostering" + description: "Corporate Staff Rostering" + children: + - name: "corporate-staff-rostering-development" + description: "Corporate Staff Rostering Development" + - name: "corporate-staff-rostering-development" + description: "Corporate Staff Rostering Development" + - name: "planetfm" + description: "PlanetFM" + children: + - name: "planetfm-development" + description: "PlanetFM Development" + - name: "planetfm-test" + description: "PlanetFM Test" diff --git a/powershell/Configs/ADConfigProdPreProd.yaml b/powershell/Configs/ADConfigProdPreProd.yaml new file mode 100644 index 000000000..a2ff48294 --- /dev/null +++ b/powershell/Configs/ADConfigProdPreProd.yaml @@ -0,0 +1,22 @@ +ActiveDirectory: + DomainNameFQDN: "prod.loc" + OUs: + - name: "ModPlatformComputers" + description: "Modernisation Platform Computers" + GPOs: + children: + - name: "corporate-staff-rostering" + description: "Corporate Staff Rostering" + children: + - name: "corporate-staff-rostering-preproduction" + description: "Corporate Staff Rostering Preproduction" + - name: "corporate-staff-rostering-production" + description: "Corporate Staff Rostering Production" + - name: "planetfm" + description: "PlanetFM" + children: + - name: "planetfm-preproduction" + description: "PlanetFM Preproduction" + - name: "planetfm-production" + description: "PlanetFM Production" + diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index 90b962092..517609f98 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -26,7 +26,7 @@ function New-ADOrganizationalUnit { New-ADOrganizationalUnit -Name "TestOU" -Path "OU=Test,DC=example,DC=com" -Description "Test OU" .OUTPUTS - PSCredentialObject + OU folder created #> [CmdletBinding()] @@ -53,4 +53,51 @@ function New-ADOrganizationalUnit { } } +function Set-OUsAndApplyGPOs { + param ( + [Parameter(Mandatory=$true)] + [psobject]$OUs, + [string]$DomainNameFQDN # Adjust the base domain DN as necessary + ) + + $ParentDN = ($DomainNameFQDN -split "\." | ForEach-Object { "DC=$_" }) -join "," + + foreach ($ou in $OUs) { + $ouDN = "OU=$($ou.name),$ParentDN" + + # Check and create OU if it doesn't exist + if (-not (Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$ouDN'" -ErrorAction SilentlyContinue)) { + New-ADOrganizationalUnit -Name $ou.name -Path $ParentDN -ProtectedFromAccidentalDeletion $false + Write-Output "Created OU: $($ou.name) at $ouDN" + } + + # # Apply GPOs TODO: put this back in and test recursively down the stack + # foreach ($gpoName in $ou.GPOs) { + # # Assuming GPOs already exist, find and link them to the OU + # $gpo = Get-GPO -Name $gpoName -ErrorAction SilentlyContinue + # if ($gpo) { + # New-GPLink -Name $gpoName -Target $ouDN + # Write-Output "Linked GPO: $gpoName to OU: $($ou.name)" + # } + # else { + # Write-Output "GPO $gpoName does not exist and cannot be linked to OU: $($ou.name)" + # } + # } + + # Recursive call for children OUs, if any, with the current OU DN as the new parent DN + if ($ou.children) { + CreateOUsAndApplyGPOs -OUs $ou.children -ParentDN $ouDN + } + } +} + +# Load YAML +# $yamlContent = Get-Content -Path "path\to\your\file.yaml" -Raw +# $adStructure = ConvertFrom-Yaml -Yaml $yamlContent + +# # Start the recursive creation and linking process +# CreateOUsAndApplyGPOs -OUs $adStructure.ActiveDirectory.OUs + + Export-ModuleMember -Function New-ADOrganizationalUnit +Export-ModuleMember -Function Set-OUsAndApplyGPOs diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 index 5f6d1a231..24a7ee7b1 100644 --- a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 +++ b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 @@ -13,14 +13,14 @@ [CmdletBinding()] param ( - [string]$DomainName = "test.loc" + [string]$DomainNameFQDN = "test.loc" ) Import-Module ModPlatformAD -Force -$DomainNameString = ($DomainName -split "\." | ForEach-Object { "DC=$_" }) -join "," +$ParentDN = ($DomainNameFQDN -split "\." | ForEach-Object { "DC=$_" }) -join "," -New-ADOrganizationalUnit -Name "ModPlatformComputers" -Path $DomainNameString -Description "Modernisation Platform Computers" -ProtectedFromAccidentalDeletion $true +New-ADOrganizationalUnit -Name "ModPlatformComputers" -Path $ParentDN -Description "Modernisation Platform Computers" -ProtectedFromAccidentalDeletion $true # set sub-level AD OU for Modernisation Platform Computers Environments $topLevelOU = "OU=ModPlatformComputers" @@ -37,10 +37,10 @@ $ApiUrl = "https://api.github.com/repos/$repoOwner/$repoName/contents/$repoPAth" $Response = Invoke-RestMethod -Uri $ApiUrl $Response | Where-Object { $_.type -eq "dir" -and $excludeTerraformEnvironments -notcontains $_.name } | ForEach-Object { $_.name } | ForEach-Object { - New-ADOrganizationalUnit -Name $_ -Path "$topLevelOU,$DomainNameString" -Description "Modernisation Platform Computers $_" -ProtectedFromAccidentalDeletion $true + New-ADOrganizationalUnit -Name $_ -Path "$topLevelOU,$ParentDN" -Description "Modernisation Platform Computers $_" -ProtectedFromAccidentalDeletion $true ForEach ($environment in $environments) { - New-ADOrganizationalUnit -Name $environment -Path "OU=$_,$topLevelOU,$DomainNameString" -Description "Modernisation Platform Computers $_ $environment" -ProtectedFromAccidentalDeletion $true + New-ADOrganizationalUnit -Name $environment -Path "OU=$_,$topLevelOU,$ParentDN" -Description "Modernisation Platform Computers $_ $environment" -ProtectedFromAccidentalDeletion $true } } diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 new file mode 100644 index 000000000..6c3fb40fd --- /dev/null +++ b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 @@ -0,0 +1,48 @@ +<# +.SYNOPSIS + Retrieve appropriate AD config for the given Modernisation Platform environment. + +.DESCRIPTION + Either pass in the domain name as a parameter, or derive the AD configuration + from EC2 tags (environment-name or domain-name). + EC2 requires permissions to get tags and the aws cli. + +.PARAMETER DomainNameFQDN + Specify the FQDN of the domain name to join + +.EXAMPLE + $ADConfig = Get-ModPlatformADConfig + +.OUTPUTS + +#> + +[CmdletBinding()] +param ( + [Parameter(Mandatory=$true)][string]$DomainNameFQDN +) + +Import-Module ModPlatformAD -Force +Import-Module powershell-yaml -Force + +$configFileName = "" + +switch($DomainNameFQDN) { + "prod.loc" { + $configFileName = "ADConfigProdPreProd.yaml" + } + "test.loc" { + $configFileName = "ADConfigDevTest.yaml" + } + default { + Write-Error "Invalid input value. Please provide either 'azure.hmpp.root' (Prod/PreProd) or 'azure.noms.root' (Dev/Test)." + exit 1 + } +} + +# Load YAML +$yaml = Get-Content -Raw -Path $PSScriptRoot + "\$configFileName" +$config = ConvertFrom-Yaml -InputObject $yaml + +Set-OUsAndApplyGPOs -OUs $config.ActiveDirectory.OUs -DomainNameFQDN $config.ActiveDirectory.DomainNameFQDN + From 3dabc3416b6c636abe6a9c6768ea68de739bbd3d Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Wed, 6 Mar 2024 11:56:01 +0000 Subject: [PATCH 07/24] add missing files to nested modules list --- powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 index c919e7fb4..fd02a1cbf 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 @@ -69,7 +69,9 @@ PowerShellVersion = '4.0' NestedModules = @('ModPlatformADComputer.psm1', 'ModPlatformADConfig.psm1', 'ModPlatformADCredential.psm1', - 'ModPlatformADDomain.psm1') + 'ModPlatformADDomain.psm1', + 'ModPlatformADGPO.psm1', + 'ModPlatformADOU.psm1') # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. FunctionsToExport = 'Rename-ModPlatformADComputer', 'Add-ModPlatformADComputer', From 0836b41018c895f0f8e9ac4969430df83edec463 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Fri, 8 Mar 2024 10:34:05 +0000 Subject: [PATCH 08/24] fix create OU recursion --- .../ModPlatformAD/ModPlatformADOU.psm1 | 8 +++++-- .../Set-ModPlatformADOUStructure.ps1 | 21 +++---------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index 517609f98..c6c5e26fe 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -57,13 +57,15 @@ function Set-OUsAndApplyGPOs { param ( [Parameter(Mandatory=$true)] [psobject]$OUs, + [string]$ParentOUs = "", [string]$DomainNameFQDN # Adjust the base domain DN as necessary ) $ParentDN = ($DomainNameFQDN -split "\." | ForEach-Object { "DC=$_" }) -join "," foreach ($ou in $OUs) { - $ouDN = "OU=$($ou.name),$ParentDN" + $currentOUDN = "OU=$($ou.name)" + $ouDN = if ($ParentOUs -eq "") { "$currentOUDN,$DomainDN" } else { "$currentOUDN,$ParentOUs,$DomainDN" } # Check and create OU if it doesn't exist if (-not (Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$ouDN'" -ErrorAction SilentlyContinue)) { @@ -86,7 +88,9 @@ function Set-OUsAndApplyGPOs { # Recursive call for children OUs, if any, with the current OU DN as the new parent DN if ($ou.children) { - CreateOUsAndApplyGPOs -OUs $ou.children -ParentDN $ouDN + $newParentOUs = if ($ParentOUs -eq "") { "$currentOUDN" } else { "$currentOUDN,$ParentOUs" } + # Increase indentation for child OUs for visual hierarchy + Set-OUHierarchy -OUs $ou.children -ParentOUs $newParentOUs -DomainNameFQDN $DomainNameFQDN } } } diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 index 6c3fb40fd..a9e42aa7e 100644 --- a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 +++ b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 @@ -19,30 +19,15 @@ [CmdletBinding()] param ( - [Parameter(Mandatory=$true)][string]$DomainNameFQDN + [Parameter(Mandatory=$true)][string]$DomainNameFQDN, + [Parameter(Mandatory=$true)][string]$ConfigFilePath ) Import-Module ModPlatformAD -Force Import-Module powershell-yaml -Force -$configFileName = "" - -switch($DomainNameFQDN) { - "prod.loc" { - $configFileName = "ADConfigProdPreProd.yaml" - } - "test.loc" { - $configFileName = "ADConfigDevTest.yaml" - } - default { - Write-Error "Invalid input value. Please provide either 'azure.hmpp.root' (Prod/PreProd) or 'azure.noms.root' (Dev/Test)." - exit 1 - } -} - # Load YAML -$yaml = Get-Content -Raw -Path $PSScriptRoot + "\$configFileName" -$config = ConvertFrom-Yaml -InputObject $yaml +$config = Get-Content -Raw -Path $ConfigFilePath | ConvertFrom-Yaml Set-OUsAndApplyGPOs -OUs $config.ActiveDirectory.OUs -DomainNameFQDN $config.ActiveDirectory.DomainNameFQDN From c63763fdfc85a41ba34f891430a4d129d9e95dcd Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Fri, 8 Mar 2024 10:41:51 +0000 Subject: [PATCH 09/24] Install the powershell-yaml module as well --- .../Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 index a9e42aa7e..71f90f452 100644 --- a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 +++ b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 @@ -23,7 +23,10 @@ param ( [Parameter(Mandatory=$true)][string]$ConfigFilePath ) +Install-Module -Name powershell-yaml -Force -SkipPublisherCheck + Import-Module ModPlatformAD -Force + Import-Module powershell-yaml -Force # Load YAML From 346194f1339eec862dae77edd194e4eef316e98c Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Mon, 11 Mar 2024 13:25:23 +0000 Subject: [PATCH 10/24] fix recursion --- .../ModPlatformAD/ModPlatformADOU.psm1 | 57 ++++++------------- .../Set-ModPlatformADOUStructure.ps1 | 7 ++- 2 files changed, 21 insertions(+), 43 deletions(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index c6c5e26fe..d2010abb2 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -56,52 +56,27 @@ function New-ADOrganizationalUnit { function Set-OUsAndApplyGPOs { param ( [Parameter(Mandatory=$true)] - [psobject]$OUs, - [string]$ParentOUs = "", - [string]$DomainNameFQDN # Adjust the base domain DN as necessary + [psobject]$Ou, + [Parameter(Mandatory=$true)] + [string]$Path # Adjust the base domain DN as necessary ) + Write-Output "Creating OU: $($ou.name)" + Write-Output "Creating Path: $Path" + Write-Output "Description: $($ou.description)" - $ParentDN = ($DomainNameFQDN -split "\." | ForEach-Object { "DC=$_" }) -join "," - - foreach ($ou in $OUs) { - $currentOUDN = "OU=$($ou.name)" - $ouDN = if ($ParentOUs -eq "") { "$currentOUDN,$DomainDN" } else { "$currentOUDN,$ParentOUs,$DomainDN" } - - # Check and create OU if it doesn't exist - if (-not (Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$ouDN'" -ErrorAction SilentlyContinue)) { - New-ADOrganizationalUnit -Name $ou.name -Path $ParentDN -ProtectedFromAccidentalDeletion $false - Write-Output "Created OU: $($ou.name) at $ouDN" - } - - # # Apply GPOs TODO: put this back in and test recursively down the stack - # foreach ($gpoName in $ou.GPOs) { - # # Assuming GPOs already exist, find and link them to the OU - # $gpo = Get-GPO -Name $gpoName -ErrorAction SilentlyContinue - # if ($gpo) { - # New-GPLink -Name $gpoName -Target $ouDN - # Write-Output "Linked GPO: $gpoName to OU: $($ou.name)" - # } - # else { - # Write-Output "GPO $gpoName does not exist and cannot be linked to OU: $($ou.name)" - # } - # } - - # Recursive call for children OUs, if any, with the current OU DN as the new parent DN - if ($ou.children) { - $newParentOUs = if ($ParentOUs -eq "") { "$currentOUDN" } else { "$currentOUDN,$ParentOUs" } - # Increase indentation for child OUs for visual hierarchy - Set-OUHierarchy -OUs $ou.children -ParentOUs $newParentOUs -DomainNameFQDN $DomainNameFQDN + # Create the OU in AD + New-ADOrganizationalUnit -Name $ou.name -Path $path -Description $ou.description -PassThru + + # Append the OU name to the path for the next level + $ouPath = "OU=$($ou.name),$path" + + # If the OU has children, call the function recursively + if ($ou.children) { + foreach ($child in $ou.children) { + Create-OU -ou $child -path $ouPath } } } -# Load YAML -# $yamlContent = Get-Content -Path "path\to\your\file.yaml" -Raw -# $adStructure = ConvertFrom-Yaml -Yaml $yamlContent - -# # Start the recursive creation and linking process -# CreateOUsAndApplyGPOs -OUs $adStructure.ActiveDirectory.OUs - - Export-ModuleMember -Function New-ADOrganizationalUnit Export-ModuleMember -Function Set-OUsAndApplyGPOs diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 index 71f90f452..c2cf7aa38 100644 --- a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 +++ b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 @@ -29,8 +29,11 @@ Import-Module ModPlatformAD -Force Import-Module powershell-yaml -Force +$ParentDN = ($DomainNameFQDN -split "\." | ForEach-Object { "DC=$_" }) -join "," + # Load YAML $config = Get-Content -Raw -Path $ConfigFilePath | ConvertFrom-Yaml -Set-OUsAndApplyGPOs -OUs $config.ActiveDirectory.OUs -DomainNameFQDN $config.ActiveDirectory.DomainNameFQDN - +foreach ($ou in $config.ActiveDirectory.OUs) { + Set-OUsAndApplyGPOs -OUs $Ou -DomainNameFQDN $ParentDN +} From 213bfb50c9aa8a0358330d5d3a85f6f9f692918a Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Mon, 11 Mar 2024 13:30:28 +0000 Subject: [PATCH 11/24] add function --- powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 index fd02a1cbf..386b3e367 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 @@ -78,7 +78,7 @@ FunctionsToExport = 'Rename-ModPlatformADComputer', 'Add-ModPlatformADComputer', 'Remove-ModPlatformADComputer', 'Get-ModPlatformADConfig', 'Get-ModPlatformADSecret', 'Get-ModPlatformADJoinCredential', 'Get-ModPlatformADAdminCredential', - 'Get-ModPlatformADSafeModeAdministratorPassword' + 'Get-ModPlatformADSafeModeAdministratorPassword','Set-OUsAndApplyGPOs' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = '*' From f4d70dd020109e9275b8707bb33c7b916938b085 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Mon, 11 Mar 2024 13:45:42 +0000 Subject: [PATCH 12/24] update function export list --- powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 index 386b3e367..a38e5805c 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 @@ -78,7 +78,7 @@ FunctionsToExport = 'Rename-ModPlatformADComputer', 'Add-ModPlatformADComputer', 'Remove-ModPlatformADComputer', 'Get-ModPlatformADConfig', 'Get-ModPlatformADSecret', 'Get-ModPlatformADJoinCredential', 'Get-ModPlatformADAdminCredential', - 'Get-ModPlatformADSafeModeAdministratorPassword','Set-OUsAndApplyGPOs' + 'Get-ModPlatformADSafeModeAdministratorPassword','Set-OUsAndApplyGPOs','Install-ModPlatformADDomain','New-ADOrganizationalUnit' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = '*' From 7e3c6913d468cde1e1357c4161de1771212c86f3 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Mon, 11 Mar 2024 16:19:37 +0000 Subject: [PATCH 13/24] fix recursion call --- powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 | 4 ++-- .../Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index d2010abb2..b13364b87 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -65,7 +65,7 @@ function Set-OUsAndApplyGPOs { Write-Output "Description: $($ou.description)" # Create the OU in AD - New-ADOrganizationalUnit -Name $ou.name -Path $path -Description $ou.description -PassThru + New-ADOrganizationalUnit -Name $ou.name -Path $path -Description $ou.description # Append the OU name to the path for the next level $ouPath = "OU=$($ou.name),$path" @@ -73,7 +73,7 @@ function Set-OUsAndApplyGPOs { # If the OU has children, call the function recursively if ($ou.children) { foreach ($child in $ou.children) { - Create-OU -ou $child -path $ouPath + Set-OUsAndApplyGPOs -ou $child -path $ouPath } } } diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 index c2cf7aa38..74617eefc 100644 --- a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 +++ b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 @@ -35,5 +35,5 @@ $ParentDN = ($DomainNameFQDN -split "\." | ForEach-Object { "DC=$_" }) -join "," $config = Get-Content -Raw -Path $ConfigFilePath | ConvertFrom-Yaml foreach ($ou in $config.ActiveDirectory.OUs) { - Set-OUsAndApplyGPOs -OUs $Ou -DomainNameFQDN $ParentDN + Set-OUsAndApplyGPOs -OU $Ou -Path $ParentDN } From a1f537dace678d0d9fad3fc842ba935a242213f5 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Tue, 12 Mar 2024 10:11:18 +0000 Subject: [PATCH 14/24] more testing data --- powershell/Configs/ADConfigDevTest.yaml | 6 ++ powershell/Configs/L1.yaml | 9 ++ powershell/Configs/L2.yaml | 17 ++++ powershell/Configs/L3.yaml | 27 ++++++ .../Modules/ModPlatformAD/ModPlatformAD.psd1 | 2 +- .../ModPlatformAD/ModPlatformADOU.psm1 | 86 +++++++++---------- 6 files changed, 103 insertions(+), 44 deletions(-) create mode 100644 powershell/Configs/L1.yaml create mode 100644 powershell/Configs/L2.yaml create mode 100644 powershell/Configs/L3.yaml diff --git a/powershell/Configs/ADConfigDevTest.yaml b/powershell/Configs/ADConfigDevTest.yaml index 93bcfa841..9fbc9e869 100644 --- a/powershell/Configs/ADConfigDevTest.yaml +++ b/powershell/Configs/ADConfigDevTest.yaml @@ -19,3 +19,9 @@ ActiveDirectory: description: "PlanetFM Development" - name: "planetfm-test" description: "PlanetFM Test" + - name: "ModPlatformUsers" + description: "Modernisation Platform Users" + GPOs: + children: + - name: "mod-platform-users" + description: "Modernisation Platform Users" diff --git a/powershell/Configs/L1.yaml b/powershell/Configs/L1.yaml new file mode 100644 index 000000000..484eda2ad --- /dev/null +++ b/powershell/Configs/L1.yaml @@ -0,0 +1,9 @@ +ActiveDirectory: + DomainNameFQDN: "test.loc" + OUs: + - name: "ModPlatformComputers" + description: "Modernisation Platform Computers" + GPOs: + - name: "ModPlatformUsers" + description: "Modernisation Platform Users" + GPOs: diff --git a/powershell/Configs/L2.yaml b/powershell/Configs/L2.yaml new file mode 100644 index 000000000..8f9edea28 --- /dev/null +++ b/powershell/Configs/L2.yaml @@ -0,0 +1,17 @@ +ActiveDirectory: + DomainNameFQDN: "test.loc" + OUs: + - name: "ModPlatformComputers" + description: "Modernisation Platform Computers" + GPOs: + children: + - name: "corporate-staff-rostering" + description: "Corporate Staff Rostering" + - name: "planetfm" + description: "PlanetFM" + - name: "ModPlatformUsers" + description: "Modernisation Platform Users" + GPOs: + children: + - name: "mod-platform-users" + description: "Modernisation Platform Users" diff --git a/powershell/Configs/L3.yaml b/powershell/Configs/L3.yaml new file mode 100644 index 000000000..9fbc9e869 --- /dev/null +++ b/powershell/Configs/L3.yaml @@ -0,0 +1,27 @@ +ActiveDirectory: + DomainNameFQDN: "test.loc" + OUs: + - name: "ModPlatformComputers" + description: "Modernisation Platform Computers" + GPOs: + children: + - name: "corporate-staff-rostering" + description: "Corporate Staff Rostering" + children: + - name: "corporate-staff-rostering-development" + description: "Corporate Staff Rostering Development" + - name: "corporate-staff-rostering-development" + description: "Corporate Staff Rostering Development" + - name: "planetfm" + description: "PlanetFM" + children: + - name: "planetfm-development" + description: "PlanetFM Development" + - name: "planetfm-test" + description: "PlanetFM Test" + - name: "ModPlatformUsers" + description: "Modernisation Platform Users" + GPOs: + children: + - name: "mod-platform-users" + description: "Modernisation Platform Users" diff --git a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 index a38e5805c..5d2919466 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 @@ -78,7 +78,7 @@ FunctionsToExport = 'Rename-ModPlatformADComputer', 'Add-ModPlatformADComputer', 'Remove-ModPlatformADComputer', 'Get-ModPlatformADConfig', 'Get-ModPlatformADSecret', 'Get-ModPlatformADJoinCredential', 'Get-ModPlatformADAdminCredential', - 'Get-ModPlatformADSafeModeAdministratorPassword','Set-OUsAndApplyGPOs','Install-ModPlatformADDomain','New-ADOrganizationalUnit' + 'Get-ModPlatformADSafeModeAdministratorPassword','Set-OUsAndApplyGPOs','Install-ModPlatformADDomain' #,'New-ADOrganizationalUnit' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = '*' diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index b13364b87..7b8c31917 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -1,57 +1,57 @@ -function New-ADOrganizationalUnit { +# function New-ADOrganizationalUnit { -<# -.SYNOPSIS - Creates a New-ADOrganizationalUnit +# <# +# .SYNOPSIS +# Creates a New-ADOrganizationalUnit -.DESCRIPTION - Using configuration returned from Get-ModPlatformADConfig, this function - optionally assumes a role to access a secret containing the password of the - domain join username. EC2 requires permissions to join the given role, - a SSM parameter containing account IDs, and the aws cli. +# .DESCRIPTION +# Using configuration returned from Get-ModPlatformADConfig, this function +# optionally assumes a role to access a secret containing the password of the +# domain join username. EC2 requires permissions to join the given role, +# a SSM parameter containing account IDs, and the aws cli. -.PARAMETER Name - Name of the Organizational Unit to create +# .PARAMETER Name +# Name of the Organizational Unit to create -.PARAMETER Path - The path of the Organizational Unit to create +# .PARAMETER Path +# The path of the Organizational Unit to create -.PARAMETER Description - Description of the Organizational Unit to create +# .PARAMETER Description +# Description of the Organizational Unit to create -.PARAMETER ProtectedFromAccidentalDeletion - Whether the Organizational Unit should be protected from accidental deletion, defaults to false +# .PARAMETER ProtectedFromAccidentalDeletion +# Whether the Organizational Unit should be protected from accidental deletion, defaults to false -.EXAMPLE - New-ADOrganizationalUnit -Name "TestOU" -Path "OU=Test,DC=example,DC=com" -Description "Test OU" +# .EXAMPLE +# New-ADOrganizationalUnit -Name "TestOU" -Path "OU=Test,DC=example,DC=com" -Description "Test OU" -.OUTPUTS - OU folder created -#> +# .OUTPUTS +# OU folder created +# #> - [CmdletBinding()] - param ( - [Parameter(Mandatory = $true)] - [string]$Name, +# [CmdletBinding()] +# param ( +# [Parameter(Mandatory = $true)] +# [string]$Name, - [Parameter(Mandatory = $true)] - [string]$Path, +# [Parameter(Mandatory = $true)] +# [string]$Path, - [Parameter(Mandatory = $false)] - [string]$Description, +# [Parameter(Mandatory = $false)] +# [string]$Description, - [Parameter(Mandatory = $false)] - [bool]$ProtectedFromAccidentalDeletion = $false - ) +# [Parameter(Mandatory = $false)] +# [bool]$ProtectedFromAccidentalDeletion = $false +# ) - $ou = Get-ADOrganizationalUnit -Filter "Name -eq '$Name'" -SearchBase $Path - if ($ou) { - Write-Host "Organizational Unit $Name already exists in $Path" -ForegroundColor Yellow - } else { - $ou = New-ADOrganizationalUnit -Name $Name -Path $Path -Description $Description -ProtectedFromAccidentalDeletion $ProtectedFromAccidentalDeletion - Write-Host "Organizational Unit $Name created in $Path" -ForegroundColor Green - } -} +# $ou = Get-ADOrganizationalUnit -Filter "Name -eq '$Name'" -SearchBase $Path +# if ($ou) { +# Write-Host "Organizational Unit $Name already exists in $Path" -ForegroundColor Yellow +# } else { +# $ou = New-ADOrganizationalUnit -Name $Name -Path $Path -Description $Description -ProtectedFromAccidentalDeletion $ProtectedFromAccidentalDeletion +# Write-Host "Organizational Unit $Name created in $Path" -ForegroundColor Green +# } +# } function Set-OUsAndApplyGPOs { param ( @@ -65,7 +65,7 @@ function Set-OUsAndApplyGPOs { Write-Output "Description: $($ou.description)" # Create the OU in AD - New-ADOrganizationalUnit -Name $ou.name -Path $path -Description $ou.description + # New-ADOrganizationalUnit -Name $ou.name -Path $path -Description $ou.description # Append the OU name to the path for the next level $ouPath = "OU=$($ou.name),$path" @@ -78,5 +78,5 @@ function Set-OUsAndApplyGPOs { } } -Export-ModuleMember -Function New-ADOrganizationalUnit +# Export-ModuleMember -Function New-ADOrganizationalUnit Export-ModuleMember -Function Set-OUsAndApplyGPOs From def455dd80c566ccc0a48b0fe36dcd3f0d0a10fd Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Tue, 12 Mar 2024 13:37:12 +0000 Subject: [PATCH 15/24] fix dodgy test data --- powershell/Configs/ADConfigDevTest.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/powershell/Configs/ADConfigDevTest.yaml b/powershell/Configs/ADConfigDevTest.yaml index 9fbc9e869..935ef9c46 100644 --- a/powershell/Configs/ADConfigDevTest.yaml +++ b/powershell/Configs/ADConfigDevTest.yaml @@ -10,8 +10,8 @@ ActiveDirectory: children: - name: "corporate-staff-rostering-development" description: "Corporate Staff Rostering Development" - - name: "corporate-staff-rostering-development" - description: "Corporate Staff Rostering Development" + - name: "corporate-staff-rostering-test" + description: "Corporate Staff Rostering Test" - name: "planetfm" description: "PlanetFM" children: From d2641dc911e17274934297e2546fbb39d13caaeb Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Tue, 12 Mar 2024 18:18:32 +0000 Subject: [PATCH 16/24] add GPO code to setupOU code --- powershell/Configs/ADConfigDevTest.yaml | 5 ++- powershell/Configs/GPOs.yaml | 13 ++++++ powershell/Configs/L3.yaml | 4 +- powershell/Configs/test.ps1 | 17 ++++++++ .../ModPlatformAD/ModPlatformADOU.psm1 | 19 ++++++--- .../ModPlatformAD/New-ModPlatformGPO.ps1 | 40 +++++++++++++++++++ 6 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 powershell/Configs/GPOs.yaml create mode 100644 powershell/Configs/test.ps1 create mode 100644 powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 diff --git a/powershell/Configs/ADConfigDevTest.yaml b/powershell/Configs/ADConfigDevTest.yaml index 935ef9c46..8d6f3af9a 100644 --- a/powershell/Configs/ADConfigDevTest.yaml +++ b/powershell/Configs/ADConfigDevTest.yaml @@ -3,7 +3,9 @@ ActiveDirectory: OUs: - name: "ModPlatformComputers" description: "Modernisation Platform Computers" - GPOs: + GPOs: + - "SetScreenSaverTimeout" + - "SetScreenSaverActive" children: - name: "corporate-staff-rostering" description: "Corporate Staff Rostering" @@ -22,6 +24,7 @@ ActiveDirectory: - name: "ModPlatformUsers" description: "Modernisation Platform Users" GPOs: + - "SetScreenSaverTimeout" children: - name: "mod-platform-users" description: "Modernisation Platform Users" diff --git a/powershell/Configs/GPOs.yaml b/powershell/Configs/GPOs.yaml new file mode 100644 index 000000000..5e00ee41b --- /dev/null +++ b/powershell/Configs/GPOs.yaml @@ -0,0 +1,13 @@ +GPOs: + - name: SetScreenSaverTimeout + comment: Set timeout to 900 seconds + key: HKCU\Software\Policies\Microsoft\Windows\Control Panel\Desktop + valuename: ScreenSaverTimeout + type: String + value: 900 + - name: SetScreenSaverActive + comment: Set screen saver to active + key: HKCU\Software\Policies\Microsoft\Windows\Control Panel\Desktop + valuename: ScreenSaveActive + type: String + value: 1 diff --git a/powershell/Configs/L3.yaml b/powershell/Configs/L3.yaml index 9fbc9e869..935ef9c46 100644 --- a/powershell/Configs/L3.yaml +++ b/powershell/Configs/L3.yaml @@ -10,8 +10,8 @@ ActiveDirectory: children: - name: "corporate-staff-rostering-development" description: "Corporate Staff Rostering Development" - - name: "corporate-staff-rostering-development" - description: "Corporate Staff Rostering Development" + - name: "corporate-staff-rostering-test" + description: "Corporate Staff Rostering Test" - name: "planetfm" description: "PlanetFM" children: diff --git a/powershell/Configs/test.ps1 b/powershell/Configs/test.ps1 new file mode 100644 index 000000000..48d7ac07c --- /dev/null +++ b/powershell/Configs/test.ps1 @@ -0,0 +1,17 @@ +# Install-Module -Name powershell-yaml -Force -SkipPublisherCheck + +# Import-Module ModPlatformAD -Force + +Import-Module powershell-yaml -Force + +# Load YAML +$config = Get-Content -Raw -Path ADConfigDevTest.yaml | ConvertFrom-Yaml + +foreach ($ou in $config.ActiveDirectory.OUs) { + Write-Host "processing OU $($ou.name)" + if ($ou.gpos) { + foreach ($gpo in $ou.gpos) { + Write-Host "processing GPO $gpo" + } + } +} diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index 7b8c31917..424f426e2 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -58,18 +58,27 @@ function Set-OUsAndApplyGPOs { [Parameter(Mandatory=$true)] [psobject]$Ou, [Parameter(Mandatory=$true)] - [string]$Path # Adjust the base domain DN as necessary + [string]$Path, # Adjusts the base domain DN as necessary + [bool]$ProtectedFromAccidentalDeletion = $false ) - Write-Output "Creating OU: $($ou.name)" - Write-Output "Creating Path: $Path" - Write-Output "Description: $($ou.description)" + Write-Debug "Creating OU: $($ou.name)" + Write-Debug "Creating Path: $Path" + Write-Debug "Description: $($ou.description)" # Create the OU in AD - # New-ADOrganizationalUnit -Name $ou.name -Path $path -Description $ou.description + New-ADOrganizationalUnit -Name $ou.name -Path $path -Description $ou.description -ProtectedFromAccidentalDeletion $ProtectedFromAccidentalDeletion # Append the OU name to the path for the next level $ouPath = "OU=$($ou.name),$path" + if ($ou.gpos) { + foreach ($gpo in $ou.gpos) { + Write-Debug "Applying GPO: $($gpo.name) to Target OU: $ouPath" + # Apply the GPO to the OU + New-GPLink -Name $gpo.name -Target $ouPath + } + } + # If the OU has children, call the function recursively if ($ou.children) { foreach ($child in $ou.children) { diff --git a/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 b/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 new file mode 100644 index 000000000..a80d1da47 --- /dev/null +++ b/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 @@ -0,0 +1,40 @@ +<# +.SYNOPSIS + Create Group Policy Objects (GPOs) for the given Modernisation Platform environment + GPO's need to be created BEFORE they can be linked to an OU. + +.DESCRIPTION + Pulls in the GPO definitions from the given YAML file and creates the GPOs in the given domain. + +.PARAMETER DomainNameFQDN + Specify the FQDN of the domain name to join + +.PARAMETER ConfigFilePath + Specify the *.yaml config file path for the given AD configuration + +.EXAMPLE + ./New-ModPlatformGPO.ps1 -DomainNameFQDN "test.loc" -ConfigFilePath "config.yaml" + +.OUTPUTS + +#> + +[CmdletBinding()] +param ( + [Parameter(Mandatory=$true)][string]$DomainNameFQDN, + [Parameter(Mandatory=$true)][string]$ConfigFilePath +) + +Install-Module -Name powershell-yaml -Force -SkipPublisherCheck + +Import-Module ModPlatformAD -Force + +Import-Module powershell-yaml -Force + +# Load YAML +$config = Get-Content -Raw -Path $ConfigFilePath | ConvertFrom-Yaml + +foreach ($gpo in $config.GPOs) { + New-GPO -Name $gpo.Name -Domain $DomainNameFQDN -Comment $gpo.Description + Set-GPRegistryValue -Name $gpo.name -Key $gpo.key -ValueName $gpo.valuename -Type $gpo.type -Value $gpo.value +} From f684ecb4e97846232e58e4afec383c1ea9b8ba19 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Wed, 13 Mar 2024 18:17:05 +0000 Subject: [PATCH 17/24] fix bugs --- powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 | 4 ++-- powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index 424f426e2..6e03d1e06 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -73,9 +73,9 @@ function Set-OUsAndApplyGPOs { if ($ou.gpos) { foreach ($gpo in $ou.gpos) { - Write-Debug "Applying GPO: $($gpo.name) to Target OU: $ouPath" + Write-Debug "Applying GPO: $gpo to Target OU: $ouPath" # Apply the GPO to the OU - New-GPLink -Name $gpo.name -Target $ouPath + New-GPLink -Name $gpo -Target $ouPath } } diff --git a/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 b/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 index a80d1da47..2d35bbf2f 100644 --- a/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 +++ b/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 @@ -35,6 +35,6 @@ Import-Module powershell-yaml -Force $config = Get-Content -Raw -Path $ConfigFilePath | ConvertFrom-Yaml foreach ($gpo in $config.GPOs) { - New-GPO -Name $gpo.Name -Domain $DomainNameFQDN -Comment $gpo.Description + New-GPO -Name $gpo.name -Domain $DomainNameFQDN -Comment $gpo.comment Set-GPRegistryValue -Name $gpo.name -Key $gpo.key -ValueName $gpo.valuename -Type $gpo.type -Value $gpo.value } From 9b92e1ac7413bf6ce190e09fa3ec4cccaa73df0b Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Fri, 15 Mar 2024 13:26:28 +0000 Subject: [PATCH 18/24] remove test files --- powershell/Configs/L1.yaml | 9 ---- powershell/Configs/L2.yaml | 17 ------- powershell/Configs/L3.yaml | 27 ----------- .../ModPlatformAD/Set-ModPlatformADOU.ps1 | 46 ------------------- 4 files changed, 99 deletions(-) delete mode 100644 powershell/Configs/L1.yaml delete mode 100644 powershell/Configs/L2.yaml delete mode 100644 powershell/Configs/L3.yaml delete mode 100644 powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 diff --git a/powershell/Configs/L1.yaml b/powershell/Configs/L1.yaml deleted file mode 100644 index 484eda2ad..000000000 --- a/powershell/Configs/L1.yaml +++ /dev/null @@ -1,9 +0,0 @@ -ActiveDirectory: - DomainNameFQDN: "test.loc" - OUs: - - name: "ModPlatformComputers" - description: "Modernisation Platform Computers" - GPOs: - - name: "ModPlatformUsers" - description: "Modernisation Platform Users" - GPOs: diff --git a/powershell/Configs/L2.yaml b/powershell/Configs/L2.yaml deleted file mode 100644 index 8f9edea28..000000000 --- a/powershell/Configs/L2.yaml +++ /dev/null @@ -1,17 +0,0 @@ -ActiveDirectory: - DomainNameFQDN: "test.loc" - OUs: - - name: "ModPlatformComputers" - description: "Modernisation Platform Computers" - GPOs: - children: - - name: "corporate-staff-rostering" - description: "Corporate Staff Rostering" - - name: "planetfm" - description: "PlanetFM" - - name: "ModPlatformUsers" - description: "Modernisation Platform Users" - GPOs: - children: - - name: "mod-platform-users" - description: "Modernisation Platform Users" diff --git a/powershell/Configs/L3.yaml b/powershell/Configs/L3.yaml deleted file mode 100644 index 935ef9c46..000000000 --- a/powershell/Configs/L3.yaml +++ /dev/null @@ -1,27 +0,0 @@ -ActiveDirectory: - DomainNameFQDN: "test.loc" - OUs: - - name: "ModPlatformComputers" - description: "Modernisation Platform Computers" - GPOs: - children: - - name: "corporate-staff-rostering" - description: "Corporate Staff Rostering" - children: - - name: "corporate-staff-rostering-development" - description: "Corporate Staff Rostering Development" - - name: "corporate-staff-rostering-test" - description: "Corporate Staff Rostering Test" - - name: "planetfm" - description: "PlanetFM" - children: - - name: "planetfm-development" - description: "PlanetFM Development" - - name: "planetfm-test" - description: "PlanetFM Test" - - name: "ModPlatformUsers" - description: "Modernisation Platform Users" - GPOs: - children: - - name: "mod-platform-users" - description: "Modernisation Platform Users" diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 deleted file mode 100644 index 24a7ee7b1..000000000 --- a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOU.ps1 +++ /dev/null @@ -1,46 +0,0 @@ -<# -.SYNOPSIS - Create an Active Directory Domain Controller in Modernisation-Platform - -.DESCRIPTION - - -.PARAMETER DomainName - -.EXAMPLE - New-ModPlatformADDomain -DomainName "domain.name.root" -#> - -[CmdletBinding()] -param ( - [string]$DomainNameFQDN = "test.loc" -) - -Import-Module ModPlatformAD -Force - -$ParentDN = ($DomainNameFQDN -split "\." | ForEach-Object { "DC=$_" }) -join "," - -New-ADOrganizationalUnit -Name "ModPlatformComputers" -Path $ParentDN -Description "Modernisation Platform Computers" -ProtectedFromAccidentalDeletion $true - -# set sub-level AD OU for Modernisation Platform Computers Environments -$topLevelOU = "OU=ModPlatformComputers" - -$repoOwner = "ministryofjustice" -$repoName = "modernisation-platform-environments" -$repoPAth = "terraform/environments" - -$environments = @("development", "test", "preproduction", "production") -$excludeTerraformEnvironments = @("example") - -$ApiUrl = "https://api.github.com/repos/$repoOwner/$repoName/contents/$repoPAth" - -$Response = Invoke-RestMethod -Uri $ApiUrl - -$Response | Where-Object { $_.type -eq "dir" -and $excludeTerraformEnvironments -notcontains $_.name } | ForEach-Object { $_.name } | ForEach-Object { - New-ADOrganizationalUnit -Name $_ -Path "$topLevelOU,$ParentDN" -Description "Modernisation Platform Computers $_" -ProtectedFromAccidentalDeletion $true - - ForEach ($environment in $environments) { - New-ADOrganizationalUnit -Name $environment -Path "OU=$_,$topLevelOU,$ParentDN" -Description "Modernisation Platform Computers $_ $environment" -ProtectedFromAccidentalDeletion $true - } -} - From dd8e4413fe4adc7e1320c953daf9a923822c2ced Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Fri, 15 Mar 2024 13:27:16 +0000 Subject: [PATCH 19/24] remove test file --- powershell/Configs/test.ps1 | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 powershell/Configs/test.ps1 diff --git a/powershell/Configs/test.ps1 b/powershell/Configs/test.ps1 deleted file mode 100644 index 48d7ac07c..000000000 --- a/powershell/Configs/test.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -# Install-Module -Name powershell-yaml -Force -SkipPublisherCheck - -# Import-Module ModPlatformAD -Force - -Import-Module powershell-yaml -Force - -# Load YAML -$config = Get-Content -Raw -Path ADConfigDevTest.yaml | ConvertFrom-Yaml - -foreach ($ou in $config.ActiveDirectory.OUs) { - Write-Host "processing OU $($ou.name)" - if ($ou.gpos) { - foreach ($gpo in $ou.gpos) { - Write-Host "processing GPO $gpo" - } - } -} From f40170313649acfb66f771b658e2c9d53365a3f7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 15 Mar 2024 13:27:56 +0000 Subject: [PATCH 20/24] Commit changes made by code formatters --- powershell/Configs/ADConfigDevTest.yaml | 4 ++-- powershell/Configs/ADConfigProdPreProd.yaml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/powershell/Configs/ADConfigDevTest.yaml b/powershell/Configs/ADConfigDevTest.yaml index 8d6f3af9a..d58bf10f9 100644 --- a/powershell/Configs/ADConfigDevTest.yaml +++ b/powershell/Configs/ADConfigDevTest.yaml @@ -3,7 +3,7 @@ ActiveDirectory: OUs: - name: "ModPlatformComputers" description: "Modernisation Platform Computers" - GPOs: + GPOs: - "SetScreenSaverTimeout" - "SetScreenSaverActive" children: @@ -24,7 +24,7 @@ ActiveDirectory: - name: "ModPlatformUsers" description: "Modernisation Platform Users" GPOs: - - "SetScreenSaverTimeout" + - "SetScreenSaverTimeout" children: - name: "mod-platform-users" description: "Modernisation Platform Users" diff --git a/powershell/Configs/ADConfigProdPreProd.yaml b/powershell/Configs/ADConfigProdPreProd.yaml index a2ff48294..c43fd96a2 100644 --- a/powershell/Configs/ADConfigProdPreProd.yaml +++ b/powershell/Configs/ADConfigProdPreProd.yaml @@ -19,4 +19,3 @@ ActiveDirectory: description: "PlanetFM Preproduction" - name: "planetfm-production" description: "PlanetFM Production" - From bc7af4ad3d6adc9d0bd44980b9d8cf5c63ffb734 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Fri, 15 Mar 2024 13:31:35 +0000 Subject: [PATCH 21/24] remove reference to my changes --- powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 | 7 ++----- powershell/Modules/ModPlatformAD/ModPlatformADGPO.psm1 | 0 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 powershell/Modules/ModPlatformAD/ModPlatformADGPO.psm1 diff --git a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 index 5d2919466..38fb45a68 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformAD.psd1 @@ -68,17 +68,14 @@ PowerShellVersion = '4.0' # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess NestedModules = @('ModPlatformADComputer.psm1', 'ModPlatformADConfig.psm1', - 'ModPlatformADCredential.psm1', - 'ModPlatformADDomain.psm1', - 'ModPlatformADGPO.psm1', - 'ModPlatformADOU.psm1') + 'ModPlatformADCredential.psm1') # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. FunctionsToExport = 'Rename-ModPlatformADComputer', 'Add-ModPlatformADComputer', 'Remove-ModPlatformADComputer', 'Get-ModPlatformADConfig', 'Get-ModPlatformADSecret', 'Get-ModPlatformADJoinCredential', 'Get-ModPlatformADAdminCredential', - 'Get-ModPlatformADSafeModeAdministratorPassword','Set-OUsAndApplyGPOs','Install-ModPlatformADDomain' #,'New-ADOrganizationalUnit' + 'Get-ModPlatformADSafeModeAdministratorPassword' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = '*' diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADGPO.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADGPO.psm1 deleted file mode 100644 index e69de29bb..000000000 From 1c88b5122ce02edee5d3a0f8e1a2a2d2107b0f99 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Fri, 15 Mar 2024 13:33:03 +0000 Subject: [PATCH 22/24] remove test file --- .../ModPlatformAD/New-ModPlatformADDomain.ps1 | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 powershell/Scripts/ModPlatformAD/New-ModPlatformADDomain.ps1 diff --git a/powershell/Scripts/ModPlatformAD/New-ModPlatformADDomain.ps1 b/powershell/Scripts/ModPlatformAD/New-ModPlatformADDomain.ps1 deleted file mode 100644 index 38dae6782..000000000 --- a/powershell/Scripts/ModPlatformAD/New-ModPlatformADDomain.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -<# -.SYNOPSIS - Create an Active Directory Domain Controller in Modernisation-Platform - -.DESCRIPTION - - -.PARAMETER DomainName - -.EXAMPLE - New-ModPlatformADDomain -DomainName "domain.name.root" -#> - -[CmdletBinding()] -param ( - [string]$DomainName = "test.loc" -) - -Import-Module ModPlatformAD -Force - -Install-ModPlatformADDomain -DomainName $DomainName \ No newline at end of file From 749cc252ef5d68f24a8f7e7de45a9e6206ece440 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Fri, 15 Mar 2024 13:36:32 +0000 Subject: [PATCH 23/24] remove test file --- .../ModPlatformAD/ModPlatformADDomain.psm1 | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 deleted file mode 100644 index fbbab186e..000000000 --- a/powershell/Modules/ModPlatformAD/ModPlatformADDomain.psm1 +++ /dev/null @@ -1,36 +0,0 @@ -function Install-ModPlatformADDomain { - -<# -.SYNOPSIS - Installs the Active Directory Domain Services Windows Feature and Domain - -.DESCRIPTION - TODO: Add this and Parameters - -.PARAMETER DomainName - Domain Name to create - -.EXAMPLE - Install-ModPlatformADDomain -DomainName "test.loc" - -.OUTPUTS - PSCredentialObject -#> - -[CmdletBinding()] -param ( - [Parameter(Mandatory=$true)][string]$DomainName -) - - $ErrorActionPreference = "Stop" - - Install-WindowsFeature AD-Domain-Services -IncludeManagementTools - - # placeholder - may need to be replaced - $SafeModeAdministratorPassword = aws secretsmanager get-secret-value --secret-id devtestDomainPassword --query 'SecretString' --output text - - Install-ADDSForest -DomainName $DomainName -InstallDNS -CreateDnsDelegation:$false -DatabasePath "C:\Windows\NTDS" -LogPath "C:\Windows\NTDS" -SYSVOLPath "C:\Windows\SYSVOL" -Force -SafeModeAdministratorPassword (ConvertTo-SecureString $SafeModeAdministratorPassword -AsPlainText -Force) - -} - -Export-ModuleMember -Function Install-ModPlatformADDomain \ No newline at end of file From ea1ba03758decb4a669fe1a9e4b5b0249f7af650 Mon Sep 17 00:00:00 2001 From: robertsweetman Date: Fri, 15 Mar 2024 13:47:05 +0000 Subject: [PATCH 24/24] tidy up code and add comments --- .../ModPlatformAD/ModPlatformADOU.psm1 | 73 ++++--------------- .../ModPlatformAD/New-ModPlatformGPO.ps1 | 1 + .../Set-ModPlatformADOUStructure.ps1 | 10 ++- 3 files changed, 24 insertions(+), 60 deletions(-) diff --git a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 index 6e03d1e06..c1e056fae 100644 --- a/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 +++ b/powershell/Modules/ModPlatformAD/ModPlatformADOU.psm1 @@ -1,59 +1,19 @@ -# function New-ADOrganizationalUnit { - -# <# -# .SYNOPSIS -# Creates a New-ADOrganizationalUnit - -# .DESCRIPTION -# Using configuration returned from Get-ModPlatformADConfig, this function -# optionally assumes a role to access a secret containing the password of the -# domain join username. EC2 requires permissions to join the given role, -# a SSM parameter containing account IDs, and the aws cli. - -# .PARAMETER Name -# Name of the Organizational Unit to create - -# .PARAMETER Path -# The path of the Organizational Unit to create - -# .PARAMETER Description -# Description of the Organizational Unit to create - -# .PARAMETER ProtectedFromAccidentalDeletion -# Whether the Organizational Unit should be protected from accidental deletion, defaults to false - -# .EXAMPLE -# New-ADOrganizationalUnit -Name "TestOU" -Path "OU=Test,DC=example,DC=com" -Description "Test OU" - -# .OUTPUTS -# OU folder created -# #> - -# [CmdletBinding()] -# param ( -# [Parameter(Mandatory = $true)] -# [string]$Name, - -# [Parameter(Mandatory = $true)] -# [string]$Path, - -# [Parameter(Mandatory = $false)] -# [string]$Description, - -# [Parameter(Mandatory = $false)] -# [bool]$ProtectedFromAccidentalDeletion = $false -# ) - -# $ou = Get-ADOrganizationalUnit -Filter "Name -eq '$Name'" -SearchBase $Path -# if ($ou) { -# Write-Host "Organizational Unit $Name already exists in $Path" -ForegroundColor Yellow -# } else { -# $ou = New-ADOrganizationalUnit -Name $Name -Path $Path -Description $Description -ProtectedFromAccidentalDeletion $ProtectedFromAccidentalDeletion -# Write-Host "Organizational Unit $Name created in $Path" -ForegroundColor Green -# } -# } - function Set-OUsAndApplyGPOs { +<# +.SYNOPSIS + Recursively creates Organizational Units (OUs) and applies Group Policy Objects (GPOs) to the given domain +.DESCRIPTION + Recursively creates Organizational Units (OUs) and applies Group Policy Objects (GPOs) to the given domain +.PARAMETER Ou + The OU to create +.PARAMETER Path + The path of the OU to create +.PARAMETER ProtectedFromAccidentalDeletion + Whether the OU should be protected from accidental deletion, defaults to false + In production environments, it is recommended to set this to true +.OUTPUTS + OU folder created +#> param ( [Parameter(Mandatory=$true)] [psobject]$Ou, @@ -87,5 +47,4 @@ function Set-OUsAndApplyGPOs { } } -# Export-ModuleMember -Function New-ADOrganizationalUnit -Export-ModuleMember -Function Set-OUsAndApplyGPOs +# Export-ModuleMember -Function Set-OUsAndApplyGPOs diff --git a/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 b/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 index 2d35bbf2f..3b505b510 100644 --- a/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 +++ b/powershell/Scripts/ModPlatformAD/New-ModPlatformGPO.ps1 @@ -16,6 +16,7 @@ ./New-ModPlatformGPO.ps1 -DomainNameFQDN "test.loc" -ConfigFilePath "config.yaml" .OUTPUTS + Check Group Policy Management tools on the server to see the GPOs created #> diff --git a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 index 74617eefc..2f42a810d 100644 --- a/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 +++ b/powershell/Scripts/ModPlatformAD/Set-ModPlatformADOUStructure.ps1 @@ -1,6 +1,6 @@ <# .SYNOPSIS - Retrieve appropriate AD config for the given Modernisation Platform environment. + Applies the OU and GPO structure to the given domain based on a yaml config file. .DESCRIPTION Either pass in the domain name as a parameter, or derive the AD configuration @@ -10,10 +10,14 @@ .PARAMETER DomainNameFQDN Specify the FQDN of the domain name to join +.PARAMETER ConfigFilePath + Path to the yaml definition of the OU/GPO structure. See ../../Configs/ADConfigDevTest.yaml for example + .EXAMPLE - $ADConfig = Get-ModPlatformADConfig + ./Set-ModPlatformADOUStructure.ps1 -DomainNameFQDN "test.loc" -ConfigFilePath "../../Configs/ADConfigDevTest.yaml" -.OUTPUTS +.NOTES + GPO's referenced in the script have to have been created FIRST before running this, otherwise GPO's will not be applied #>