Files
AD-TIER/Import-TIER-GPO.ps1
2024-02-16 08:29:27 +00:00

287 lines
12 KiB
PowerShell

#Requires -Version 3 -RunAsAdministrator
#Requires -Modules ActiveDirectory, GroupPolicy
<#
.Synopsis
Import TIER GPO policy
.DESCRIPTION
Import GPO policy for TIERing and the necessary structure of objects
.EXAMPLE
.EXAMPLE
.EXAMPLE
.INPUTS
.NOTES
Author: Petr Štěpán
Email: pstepan@totalservice.cz
Release date: 13.2.2024
Revision date: 13.2.2024
Version: 1.0
.LINK
https://git.totalservice.cz/xxxxxxxx
https://totalservice.atlassian.net/browse/KB-316
#>
Param
(
# WorkFolderPath - working dir for script and download assets
[String]
$WorkFolderPath = (Join-Path -Path $env:homedrive -ChildPath 'Temp\TIER'),
# TranscriptFileName - File name of script log
[String]
$TranscriptFileName = "Script_$(Get-Date -Format 'yyyMMdd_HHmmss').log",
# GPOBackupZipFileName - Name of GPO backup zip file
[String]
$GPOBackupZipFileName = 'GPO_TIER.zip',
# DownloadURLGPOBackup - URL for downloading GPO backup file
[String]
$DownloadURLGPOBackup = 'https://git.totalservice.cz/public/AD-TIER/raw/branch/main/GPO_TIER.zip'
)
Begin
{
$ErrorActionPreference = "Stop"
#Start Transcript
Start-Transcript -Path (Join-Path -Path $WorkFolderPath -ChildPath $TranscriptFileName)
#Script start running time
$StartScriptTime = Get-Date
#### FUNCTIONS ###
#Sending messages to console
function Write-Message([string]$Message, [ValidateSet("Info","Warning","Error","Success")]$Severity="Info")
{
[string]$Time = (Get-Date -Format "HH:mm:ss").Trim()
[string]$Count = ((Get-Date) - $StartScriptTime)
switch($Severity)
{
"Info" {Write-Host $Time"|"$Count "-" $Message; Break}
"Warning" {Write-Host $Time"|"$Count "-" $Message -ForegroundColor Yellow; Break}
"Error" {Write-Host $Time"|"$Count "-" $Message -ForegroundColor Red; Break}
"Success" {Write-Host $Time"|"$Count "-" $Message -ForegroundColor Green; Break}
}
}
function Create-ADTierStructure([string]$DistinguishedName)
{
Write-Message -Message "Creating OU structure"
New-ADOrganizationalUnit -Name "Admins" -Path $DistinguishedName
New-ADOrganizationalUnit -Name "Domain" -Path "OU=Admins,$DistinguishedName"
New-ADOrganizationalUnit -Name "Servers" -Path "OU=Admins,$DistinguishedName"
New-ADOrganizationalUnit -Name "Workstations" -Path "OU=Admins,$DistinguishedName"
Write-Message -Message "Creating Security Groups"
$group = New-ADGroup -Name "AD Managers" -SamAccountName "AD Managers" -GroupCategory Security -GroupScope Global -DisplayName "AD Managers" -Path "OU=Domain,OU=Admins,$DistinguishedName" -Description "Group for managing un-privileged accounts in AD." -PassThru
$ADGroupMapping.ADManagers = "$($group.SamAccountName)@$FQDN"
$group = New-ADGroup -Name "Server Admins" -SamAccountName "Server Admins" -GroupCategory Security -GroupScope Global -DisplayName "Server Admins" -Path "OU=Servers,OU=Admins,$DistinguishedName" -Description "Managing servers in TIER 1" -PassThru
$ADGroupMapping.ServerAdmins = "$($group.SamAccountName)@$FQDN"
$group = New-ADGroup -Name "Workstation Admins" -SamAccountName "Workstation Admins" -GroupCategory Security -GroupScope Global -DisplayName "Workstation Admins" -Path "OU=Workstations,OU=Admins,$DistinguishedName" -Description "Managing workstations TIER 2" -PassThru
$ADGroupMapping.WorkstationAdmins = "$($group.SamAccountName)@$FQDN"
Write-Message -Message "Moving privileged grups to Admin\Domain OU."
Get-ADGroup "Domain Admins" | Move-ADObject -TargetPath "OU=Domain,OU=Admins,$DistinguishedName"
Get-ADGroup "Enterprise Admins" | Move-ADObject -TargetPath "OU=Domain,OU=Admins,$DistinguishedName"
Get-ADGroup "Schema Admins" | Move-ADObject -TargetPath "OU=Domain,OU=Admins,$DistinguishedName"
}
#### FUNCTIONS END ###
#Find FQDN and NetBIOS names
Write-Message -Message "Finding FQDN and NetBIOS name"
$FQDN = (Get-ADDomain).DNSRoot
$DistinguishedName = (Get-ADDomain).DistinguishedName
Write-Message -Message ('FQDN is: {0} and DistinguishedName is: {1}' -f $FQDN, $DistinguishedName)
#### VARIABLES ####
$ADGroupMapping = @{
"ServerAdmins" = ""
"WorkstationAdmins" = ""
"ADManagers" = ""
"Administrator" = "Administrator@$FQDN"
"DomainAdmins" = "Domain Admins@$FQDN"
"EnterpriseAdmins" = "Enterprise Admins@$FQDN"
}
#### END VARIABLES ####
#Find GPO backup file zip
Write-Message -Message ("Finding GPO backup zip file ({0})" -f $GPOBackupZipFileName)
If (!(Test-Path -Path (Join-Path -Path $WorkFolderPath -ChildPath $GPOBackupZipFileName)))
{
Write-Message -Message ("{0} not found. Starting downloading ..." -f $GPOBackupZipFileName)
#Download GPO Backup zip file
Write-Message -Message "Downloading GPO backup file"
$DownloadStartTime = Get-Date
#Certificate work around
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri $DownloadURLGPOBackup -OutFile (Join-Path -Path $WorkFolderPath -ChildPath $GPOBackupZipFileName)
Write-Message -Message ('Downloaded in: {0} second(s)' -f ((Get-Date) - $DownloadStartTime)) -Severity Success
}else{
Write-Message -Message ("{0} found in shared folder" -f $GPOBackupZipFileName) -Severity Success
}
#Unpack GPO backupfile
Write-Message -Message ("Unpacking GPO backup file {0}" -f $GPOBackupZipFileName)
Expand-Archive -LiteralPath (Join-Path -Path $WorkFolderPath -ChildPath $GPOBackupZipFileName) -DestinationPath $WorkFolderPath -Force
}
Process
{
Write-Host "Example:
fqdn.contoso.com/
├─ Admins/
│ ├─ Domain/
│ │ ├─ AD Managers
│ ├─ Servers/
│ │ ├─ Server Admins
│ ├─ Workstations/
│ │ ├─ Workstation Admins
├─ .../
├─ .../
├─ Computers/"
$createDefaultADStructure = ''
do {
$answer = $(Write-Host "Do you want to import default OU and Security Groups structure? [Y/N] " -ForegroundColor Yellow -NoNewline; Read-Host)
switch (($answer).ToLower()) {
"y" { $createDefaultADStructure = $true; break; }
"n" { $createDefaultADStructure = $false; break;}
Default {}
}
} until (
($createDefaultADStructure -eq $true) -or ($createDefaultADStructure -eq $false)
)
if($createDefaultADStructure){
Write-Message -Message "Generating OU a Security Groups structure"
Create-ADTierStructure($DistinguishedName)
}else {
Write-Message -Message "Manual Security Group mapping choosen"
Write-Message -Message "Getting group name for Server Admins"
# Server Admins
do {
$exist = $false
$group = $(Write-Host "Enter SamAccount name of group for SERVER ADMINS: " -ForegroundColor Yellow -NoNewline; Read-Host)
$exist = Get-ADGroup -Filter {SamAccountName -eq $group}
if($exist -eq $null) {
Write-Message -Message ("Group {0} doesn't exist" -f $group) -Severity Error
}else{
$ADGroupMapping.ServerAdmins = "$($group)@$FQDN"
}
} until (
$exist -ne $null
)
Write-Message -Message "Getting group name for Workstation Admins"
# Workstation Admins
do {
$exist = $false
$group = $(Write-Host "Enter SamAccount name of group for WORKSTATION ADMINS: " -ForegroundColor Yellow -NoNewline; Read-Host)
$exist = Get-ADGroup -Filter {SamAccountName -eq $group}
if($exist -eq $null) {
Write-Message -Message ("Group {0} doesn't exist" -f $group) -Severity Error
}else{
$ADGroupMapping.WorkstationAdmins = "$($group)@$FQDN"
}
} until (
$exist -ne $null
)
Write-Message -Message "Getting group name for AD Managers"
# AD Managers
do {
$exist = $false
$group = $(Write-Host "Enter SamAccount name of group for AD MANAGERS: " -ForegroundColor Yellow -NoNewline; Read-Host)
$exist = Get-ADGroup -Filter {SamAccountName -eq $group}
if($exist -eq $null) {
Write-Message -Message ("Group {0} doesn't exist" -f $group) -Severity Error
}else{
$ADGroupMapping.ADManagers = "$($group)@$FQDN"
}
} until (
$exist -ne $null
)
}
#Prepare GPO
#Reference https://gallery.technet.microsoft.com/Migrate-Group-Policy-2b5067d8#content
#Change variables in the GPO migration table to suit environment by recursing through the migration table and then changing the values to suit the current environment.
Write-Message -Message "Modifying GPO migration table"
$MigrationTable = "$WorkFolderPath\Migration.migtable"
(Get-Content $MigrationTable).replace("\\SHAREFOLDER", "$ShareFolder") | Set-Content $MigrationTable
Write-Message -Message "Modifying GPO migration table for SEC-ADMIN-DOMAIN"
$MigrationTable = "$WorkFolderPath\SEC-Admin-Domain.migtable"
$content = Get-Content $MigrationTable
foreach($object in $ADGroupMapping){
$content.Replace("[[$($object.Name)]]", $object.Value)
}
Set-Content $MigrationTable
Write-Message -Message "Modifying GPO migration table for SEC-ADMIN-SERVERS"
$MigrationTable = "$WorkFolderPath\SEC-Admin-Servers.migtable"
$content = Get-Content $MigrationTable
foreach($object in $ADGroupMapping){
$content.Replace("[[$($object.Name)]]", $object.Value)
}
Set-Content $MigrationTable
Write-Message -Message "Modifying GPO migration table for SEC-ADMIN-WORKSTATIONS"
$MigrationTable = "$WorkFolderPath\SEC-Admin-Workstations.migtable"
$content = Get-Content $MigrationTable
foreach($object in $ADGroupMapping){
$content.Replace("[[$($object.Name)]]", $object.Value)
}
Set-Content $MigrationTable
#Import GPO
Write-Message -Message "Importing GPO policy SEC-ADMIN-DOMAIN"
$GPOName = $(Write-Host "Enter name for GPO policy DOMAIN TIER (T0) [SEC-Admin-Domain] " -ForegroundColor Yellow -NoNewline; Read-Host)
if ($GPOName -eq '') {$GPOName = "SEC-Admin-Domain"}
Import-GPO -CreateIfNeeded -path "$WorkFolderPath" -BackupGpoName 'SEC-Admin-Domain' -TargetName $GPOName -MigrationTable "$WorkFolderPath\SEC-Admin-Domain.migtable"
Write-Message -Message "Importing GPO policy SEC-ADMIN-SERVERS"
$GPOName = $(Write-Host "Enter name for GPO policy SERVERS TIER (T1) [SEC-Admin-Servers] " -ForegroundColor Yellow -NoNewline; Read-Host)
if ($GPOName -eq '') {$GPOName = "SEC-Admin-Servers"}
Import-GPO -CreateIfNeeded -path "$WorkFolderPath" -BackupGpoName 'SEC-Admin-Servers' -TargetName $GPOName -MigrationTable "$WorkFolderPath\SEC-Admin-Servers.migtable"
Write-Message -Message "Importing GPO policy SEC-ADMIN-WORKSTATIONS"
$GPOName = $(Write-Host "Enter name for GPO policy SERVERS TIER (T1) [SEC-Admin-Workstations] " -ForegroundColor Yellow -NoNewline; Read-Host)
if ($GPOName -eq '') {$GPOName = "SEC-Admin-Workstations"}
Import-GPO -CreateIfNeeded -path "$WorkFolderPath" -BackupGpoName 'SEC-Admin-Workstations' -TargetName $GPOName -MigrationTable "$WorkFolderPath\SEC-Admin-Workstations.migtable"
}
End
{
Write-Message -Message "Hotovo!" -Severity Success
Write-Message -Message "!!!POZOR!!! Před nalinkováním GPO politik na OU kde jsou servery nebo stanice si nejprve všechny nové politiky pozorně projdi a zvaž jejich dopad na konkrétní infrastrukturu klienta. Je doporučeno politiky nasazovat postupně a nejprve na malou pilotní skupinu. Nezapomeň také vytvořit nebo přidat uživatele do nově vytvořených security skupin." -Severity Warning
#Stop Transcript
Write-Message -Message $(Stop-Transcript)
}