summaryrefslogtreecommitdiff
path: root/ansible/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'ansible/scripts')
-rw-r--r--ansible/scripts/cleanup.ps19
-rw-r--r--ansible/scripts/dc-wait-for-ready.ps117
-rw-r--r--ansible/scripts/init.ps110
-rw-r--r--ansible/scripts/install-software.ps110
-rw-r--r--ansible/scripts/join-domain.ps114
-rw-r--r--ansible/scripts/join-domain.sh46
-rw-r--r--ansible/scripts/populate-ad.ps1318
-rw-r--r--ansible/scripts/setup-adcs-esc.ps120
-rw-r--r--ansible/scripts/setup-adcs.ps150
-rw-r--r--ansible/scripts/setup-child-domain.ps150
-rw-r--r--ansible/scripts/setup-gpo.ps129
-rw-r--r--ansible/scripts/setup-iis.ps1128
-rw-r--r--ansible/scripts/setup-main-domain.ps145
-rw-r--r--ansible/scripts/setup-mssql-link.ps118
-rw-r--r--ansible/scripts/setup-mssql.ps190
-rw-r--r--ansible/scripts/setup-tree-domain.ps150
16 files changed, 904 insertions, 0 deletions
diff --git a/ansible/scripts/cleanup.ps1 b/ansible/scripts/cleanup.ps1
new file mode 100644
index 0000000..8ac42bf
--- /dev/null
+++ b/ansible/scripts/cleanup.ps1
@@ -0,0 +1,9 @@
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+Remove-Item -Path C:\tmp -Recurse -Force
+Remove-Item -Path C:\setup -Recurse -Force
+Remove-Item -Path C:\scripts -Recurse -Force
+Remove-Item -Path C:\software -Recurse -Force
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/dc-wait-for-ready.ps1 b/ansible/scripts/dc-wait-for-ready.ps1
new file mode 100644
index 0000000..afdf8ee
--- /dev/null
+++ b/ansible/scripts/dc-wait-for-ready.ps1
@@ -0,0 +1,17 @@
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+while ($true) {
+ try {
+ Write-Host "[INFO] Checking if domain is ready"
+ Get-ADDomain
+ break
+ } catch {
+ Write-Host "[INFO] Sleeping for 60s"
+ Start-Sleep -Seconds 60
+ }
+}
+
+Write-Host "[INFO] Domain is ready"
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/init.ps1 b/ansible/scripts/init.ps1
new file mode 100644
index 0000000..d6b9ff7
--- /dev/null
+++ b/ansible/scripts/init.ps1
@@ -0,0 +1,10 @@
+New-Item -Path C:\Logs -ItemType Directory -Force
+New-Item -Path C:\BgInfo -ItemType Directory -Force
+New-Item -Path C:\setup -ItemType Directory -Force
+
+Write-Host "[INFO] Disabling password complexity policy"
+secedit /export /cfg C:\secpol.cfg
+(Get-Content C:\secpol.cfg).replace("PasswordComplexity = 1", "PasswordComplexity = 0") | Out-File C:\secpol.cfg
+secedit /configure /db C:\Windows\security\local.sdb /cfg C:\secpol.cfg /areas SECURITYPOLICY
+Remove-Item -Force C:\secpol.cfg -Confirm:$false
+
diff --git a/ansible/scripts/install-software.ps1 b/ansible/scripts/install-software.ps1
new file mode 100644
index 0000000..db0f10d
--- /dev/null
+++ b/ansible/scripts/install-software.ps1
@@ -0,0 +1,10 @@
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction SilentlyContinue
+Start-Process -FilePath "C:\software\Sysmon64.exe" -ArgumentList "-accepteula -i C:\software\sysmonconfig-export.xml" -Wait -Verbose
+Start-Process -FilePath "C:\Windows\System32\MsiExec.exe" -ArgumentList "/i C:\software\googlechromestandaloneenterprise64.msi /qb" -Wait -Verbose
+Start-Process -FilePath "C:\software\npp.exe" -ArgumentList "/S" -Wait -Verbose
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "bginfo", "C:\BgInfo\Bginfo.exe C:\BgInfo\BgInfo.bgi /timer:00 /nolicprompt /silent")
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/join-domain.ps1 b/ansible/scripts/join-domain.ps1
new file mode 100644
index 0000000..08c90b2
--- /dev/null
+++ b/ansible/scripts/join-domain.ps1
@@ -0,0 +1,14 @@
+param
+(
+ [string]$DomainName = "contoso.com",
+ [string]$Username = "Administrator",
+ [string]$Password = "packer"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\$scriptName_log.txt"
+Start-Transcript -Path $logFile -Append
+
+$p = ConvertTo-SecureString $Password -AsPlainText -Force
+$c = New-Object System.Management.Automation.PSCredential($Username, $p)
+Add-Computer -DomainName $DomainName -Credential $c
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/join-domain.sh b/ansible/scripts/join-domain.sh
new file mode 100644
index 0000000..24c87b0
--- /dev/null
+++ b/ansible/scripts/join-domain.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+[[ $EUID -ne 0 ]] && printf "%s\n" "run as root" && exit 1
+
+while getopts "d:n:p:" arg; do
+ case $arg in
+ d) domain="${OPTARG}";;
+ n) nameserver="${OPTARG}";;
+ p) password="${OPTARG}";;
+ esac
+done
+
+DEBIAN_FRONTEND=noninteractive apt-get update -yqq &>/dev/null
+DEBIAN_FRONTEND=noninteractive apt-get install -yqq realmd sssd sssd-tools libnss-sss libpam-sss adcli samba-common-bin oddjob oddjob-mkhomedir packagekit krb5-user &>/dev/null
+DEBIAN_FRONTEND=noninteractive apt-get autoremove --purge -yqq &>/dev/null
+DEBIAN_FRONTEND=noninteractive apt-get clean &>/dev/null
+DEBIAN_FRONTEND=noninteractive apt-get autoclean &>/dev/null
+
+if systemctl is-active systemd-resolved; then
+ systemctl disable --now systemd-resolved --no-pager
+ systemctl mask systemd-resolved --no-pager
+fi
+
+rm -rf /etc/resolv.conf
+cat > /etc/resolv.conf << EOF
+nameserver ${nameserver}
+EOF
+chattr +i /etc/resolv.conf
+
+if realm discover $domain; then
+ echo $password | realm join $domain
+ printf "%s\n" "[INFO] Joined ${domain}"
+else
+ printf "%s\n" "[ERR] Failed to discover ${domain}"
+fi
+
+mkdir -p /usr/share/pam-configs &>/dev/null
+cat > /usr/share/pam-configs/mkhomedir << EOF
+Name: Create home directory on login
+Default: yes
+Priority: 900
+Session-Type: Additional
+Session:
+ optional pam_mkhomedir.so
+EOF
+DEBIAN_FRONTEND=noninteractive pam-auth-update --enable mkhomedir
diff --git a/ansible/scripts/populate-ad.ps1 b/ansible/scripts/populate-ad.ps1
new file mode 100644
index 0000000..0b57c77
--- /dev/null
+++ b/ansible/scripts/populate-ad.ps1
@@ -0,0 +1,318 @@
+param
+(
+ [string]$DomainName = "contoso.com",
+ [string]$FunctionalLevel = "WinThreshold",
+ [string]$UserPassword = "User1234!",
+ [string]$ServiceUserPassword = "Svc1234!"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+$DomainNameDN = "DC=$($DomainName.Split(".")[0]),DC=$($DomainName.Split(".")[1])"
+$DomainOU = $DomainName.Split(".")[0]
+$UsersOU = "Users"
+$ComputersOU = "Computers"
+$ServiceAccountsOU = "Service Accounts"
+
+Function Get-RandomObject {
+ [CmdletBinding()]
+ param(
+ [Parameter()]
+ [switch]$User,
+ [Parameter()]
+ [switch]$Computer
+ )
+
+ if ($User) {
+ return (Get-ADUser -Filter 'Description -notlike "*"' -SearchBase "OU=$UsersOU,OU=$DomainOU,$DomainNameDN" -Properties Description | Get-Random)
+ }
+
+ if ($Computer) {
+ return (Get-ADComputer -Filter 'Description -notlike "*"' -SearchBase "OU=$ComputersOU,OU=$DomainOU,$DomainNameDN" -Properties Description | Get-Random)
+ }
+}
+
+Function SetAcl($for, $to, $right, $inheritance)
+{
+ Set-Location AD:
+ $forSID = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser $for).SID
+ $objOU = ($to).DistinguishedName
+ $objAcl = get-acl $objOU
+ $adRight = [System.DirectoryServices.ActiveDirectoryRights] $right
+ $type = [System.Security.AccessControl.AccessControlType] "Allow"
+ $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] $inheritance
+ $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $forSID,$adRight,$type,$inheritanceType
+ $objAcl.AddAccessRule($ace)
+ Set-Acl -AclObject $objAcl -path $objOU
+ Set-ADObject $for -Description "$right on $($to | Select-Object -ExpandProperty Name)"
+ Set-ADObject $to -Description "$($for | Select-Object -ExpandProperty Name) has $right on this object"
+}
+
+Function SetAclExtended($for, $to, $right, $extendedRightGUID, $inheritance)
+{
+ Set-Location AD:
+ $forSID = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser $for).SID
+ $objOU = ($to).DistinguishedName
+ $objAcl = get-acl $objOU
+ $adRight = [System.DirectoryServices.ActiveDirectoryRights] $right
+ $type = [System.Security.AccessControl.AccessControlType] "Allow"
+ $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] $inheritance
+ $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $forSID,$adRight,$type,$extendedRightGUID,$inheritanceType
+ $objAcl.AddAccessRule($ace)
+ Set-Acl -AclObject $objAcl -path $objOU
+ Set-ADObject $for -Description "$right, $extendedRightGUID on $($to | Select-Object -ExpandProperty Name)"
+ Set-ADObject $to -Description "$($for | Select-Object -ExpandProperty Name) has $right, $extendedRightGUID on this object"
+}
+
+Write-Host "[INFO] Setting weak NTLM compatibility level"
+Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LmCompatibilityLevel" -Value 1 -Force
+
+If (-Not (Get-ADOrganizationalUnit -SearchBase "$DomainNameDN" -Filter "Name -like '$DomainOU'")) {
+ New-ADOrganizationalUnit -Name "$DomainOU" -Path "$DomainNameDN"
+}
+
+if (-Not (Get-ADOrganizationalUnit -SearchBase "OU=$DomainOU,$DomainNameDN" -Filter "Name -like '$UsersOU'")) {
+ New-ADOrganizationalUnit -Name "$UsersOU" -Path "OU=$DomainOU,$DomainNameDN"
+}
+
+if (-Not (Get-ADOrganizationalUnit -SearchBase "OU=$DomainOU,$DomainNameDN" -Filter "Name -like '$ComputersOU'")) {
+ New-ADOrganizationalUnit -Name "$ComputersOU" -Path "OU=$DomainOU,$DomainNameDN"
+}
+
+if (-Not (Get-ADOrganizationalUnit -SearchBase "OU=$DomainOU,$DomainNameDN" -Filter "Name -like '$ServiceAccountsOU'")) {
+ New-ADOrganizationalUnit -Name "$ServiceAccountsOU" -Path "OU=$DomainOU,$DomainNameDN"
+}
+
+$users = @("michael","christopher","jessica","matthew","ashley","jennifer","joshua","amanda","daniel","david","james","robert","john","joseph","andrew","ryan","brandon","jason","justin","sarah","william","jonathan","stephanie","brian","nicole","nicholas","anthony","heather","eric","elizabeth","adam","megan","melissa","kevin","steven","thomas","timothy","christina","kyle","rachel","laura","lauren","amber","brittany","danielle","richard","kimberly","jeffrey","amy","crystal","michelle","tiffany","jeremy","benjamin","mark","emily","aaron","charles","rebecca","jacob","stephen","patrick","sean","erin","zachary","jamie","kelly","samantha","nathan","sara","dustin","paul","angela","tyler","scott","katherine","andrea","gregory","erica","mary","travis","lisa","kenneth","bryan","lindsey","kristen","jose","alexander","jesse","katie","lindsay","shannon","vanessa","courtney","christine","alicia","cody","allison","bradley","samuel")
+
+$created_users = @()
+ForEach ($user in $users) {
+ try {
+ New-ADUser -Name "$user" `
+ -SamAccountName "$user" `
+ -EmailAddress "$user@$($DomainName.ToLower())" `
+ -Path "OU=$UsersOU,OU=$DomainOU,$DomainNameDN" `
+ -AccountPassword (ConvertTo-SecureString -AsPlainText -Force $UserPassword) `
+ -Enabled $true `
+ -PasswordNeverExpires $true
+ $created_users += $user
+ } catch {
+ Write-Host "[ERR] Failed to create user $user"
+ }
+}
+
+Get-RandomObject -User | % { Add-ADGroupMember -Identity "Domain Admins" -Members $_; Set-ADUser -Identity $_ -Description "domain admin" }
+Get-RandomObject -User | % { Add-ADGroupMember -Identity "Domain Admins" -Members $_; Set-ADUser -Identity $_ -Description "domain admin" }
+
+Write-Host "[INFO] Created users: $($created_users -Join ', ')"
+
+$created_computers = @()
+1..20 | % {
+ $servers = @("srv", "sql", "smb")
+ ForEach ($server in $servers) {
+ try {
+ New-ADComputer -SamAccountName "$server$_" -Name "$server$_" -DNSHostName "$server$_.$DomainName" -Path "OU=$ComputersOU,OU=$DomainOU,$DomainNameDN"
+ $created_computers += $server
+ } catch {
+ Write-Host "[ERR] Failed to create server $server$_"
+ }
+ }
+}
+
+Write-Host "[INFO] Created computers: $($created_computers -Join ', ')"
+
+$svc_users = @{
+ "svc_mssql01" = @{"type" = "spn"; "value" = "MSSQLSVC"}
+ "svc_mssql02" = @{"type" = "spn"; "value" = "MSSQLSVC"}
+ "svc_cifs01" = @{"type" = "spn"; "value" = "CIFS"}
+ "svc_cifs02" = @{"type" = "spn"; "value" = "CIFS"}
+ "svc_iis01" = @{"type" = "spn"; "value" = "HTTP"}
+ "svc_iis02" = @{"type" = "spn"; "value" = "HTTP"}
+ "svc_backup01" = @{"type" = "group"; "value" = "Backup Operators"}
+ "svc_backup02" = @{"type" = "group"; "value" = "Backup Operators"}
+ "svc_dns01" = @{"type" = "group"; "value" = "DnsAdmins"}
+ "svc_dns02" = @{"type" = "group"; "value" = "DnsAdmins"}
+ "svc_srvoperator01" = @{"type" = "group"; "value" = "Server Operators"}
+ "svc_srvoperator02" = @{"type" = "group"; "value" = "Server Operators"}
+ "svc_evtvwr01" = @{"type" = "group"; "value" = "Event Log Readers"}
+ "svc_evtvwr02" = @{"type" = "group"; "value" = "Event Log Readers"}
+ "svc_acctoperator01" = @{"type" = "group"; "value" = "Account Operators"}
+ "svc_acctoperator02" = @{"type" = "group"; "value" = "Account Operators"}
+ "svc_printoperator01" = @{"type" = "group"; "value" = "Print Operators"}
+ "svc_printoperator02" = @{"type" = "group"; "value" = "Print Operators"}
+ "svc_mgmtuser01" = @{"type" = "group"; "value" = "Remote Management Users"}
+ "svc_mgmtuser02" = @{"type" = "group"; "value" = "Remote Management Users"}
+}
+
+$created_svc_users = @()
+ForEach ($user in $svc_users.keys) {
+ $type = $svc_users[$user]["type"]
+ $value = $svc_users[$user]["value"]
+
+ Switch ("$type") {
+ "spn" {
+ try {
+ $comp = (Get-RandomObject -Computer | Select-Object -ExpandProperty DNSHostName)
+ $u = New-ADUser -Name "$user" `
+ -SamAccountName "$user" `
+ -AccountPassword (ConvertTo-SecureString -AsPlainText -Force $ServiceUserPassword) `
+ -Path "OU=$ServiceAccountsOU,OU=$DomainOU,$DomainNameDN" `
+ -Enabled $true `
+ -PasswordNeverExpires $true `
+ -PassThru
+ Set-ADUser -Identity "$u" -ServicePrincipalNames @{Add="$value/$comp"}
+ Set-ADObject $u -Description "SPN on $value/$comp"
+
+ $created_svc_users += "$user ($value/$comp)"
+ } catch {
+ Write-Host "[ERR] Failed to create $value/$comp for $user"
+ }
+ }
+ "group" {
+ try {
+ $u = New-ADUser -Name "$user" `
+ -SamAccountName "$user" `
+ -AccountPassword (ConvertTo-SecureString -AsPlainText -Force $UserPassword) `
+ -Path "OU=$ServiceAccountsOU,OU=$DomainOU,$DomainNameDN" `
+ -Enabled $true `
+ -PasswordNeverExpires $true `
+ -PassThru
+ Add-ADGroupMember -Identity "$value" -Members $u
+ Set-ADObject $u -Description "member of $value"
+
+ $created_svc_users += "$user ($value)"
+ } catch {
+ Write-Host "[ERR] Failed to add $user to $value"
+ }
+ }
+ }
+}
+
+Write-Host "[INFO] Created svc users: $($created_svc_users -Join ', ')"
+
+$dcsync_user = Get-RandomObject -User
+$acl = Get-Acl -Path "AD:$DomainNameDN"
+$sid = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser $dcsync_user).SID
+$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
+ -ArgumentList @($sid, [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight, [System.Security.AccessControl.AccessControlType]::Allow, [Guid]"1131f6aa-9c07-11d1-f79f-00c04fc2dcd2")))
+$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
+ -ArgumentList @($sid, [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight, [System.Security.AccessControl.AccessControlType]::Allow, [Guid]"1131f6ad-9c07-11d1-f79f-00c04fc2dcd2")))
+Set-Acl -Path "AD:$DomainNameDN" -AclObject $acl
+Set-ADObject $dcsync_user -Description "DCSync rights on $DomainName"
+
+$adminsdholder_user = Get-RandomObject -User
+$adminsdholder = "CN=AdminSDHolder,CN=System,$DomainNameDN"
+$acl = Get-Acl -Path "AD:$adminsdholder"
+$sid = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser $adminsdholder_user).SID
+$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
+ -ArgumentList @($sid, [System.DirectoryServices.ActiveDirectoryRights]::GenericAll, [System.Security.AccessControl.AccessControlType]::Allow)))
+Set-Acl -Path "AD:$adminsdholder" -AclObject $acl
+Set-ADObject $adminsdholder_user -Description "GenericAll on AdminSDHolder"
+
+Write-Host "[INFO] Configuring anonymous LDAP binding via dsHeuristics for contoso.com"
+$rootDSE = Get-ADRootDSE
+$configNC = $rootDSE.ConfigurationNamingContext
+$directoryServicePath = "CN=Directory Service,CN=Windows NT,CN=Services,$configNC"
+$directoryService = Get-ADObject -Identity $directoryServicePath -Properties dsHeuristics
+$currentHeuristics = $directoryService.dsHeuristics
+$newHeuristics = "0000002"
+Write-Host "[INFO] Overwriting dsHeuristics with '0000002'"
+Set-ADObject -Identity $directoryServicePath `
+ -Replace @{"dsHeuristics" = $newHeuristics} `
+ -Description "Anonymous LDAP enabled for contoso.com" `
+ -ErrorAction Stop
+Write-Host "[INFO] Successfully set dsHeuristics to '$newHeuristics'"
+
+Set-ADDomain -Identity $DomainName -Replace @{"ms-DS-MachineAccountQuota"=50}
+
+$dc = (Get-ADDomainController | Select-Object -ExpandProperty HostName)
+$u = New-ADUser -Name "svc_iis03" `
+ -SamAccountName "svc_iis03" `
+ -Path "OU=$ServiceAccountsOU,OU=$DomainOU,$DomainNameDN" `
+ -AccountPassword (ConvertTo-SecureString -AsPlainText -Force $ServiceUserPassword) `
+ -Enabled $true `
+ -PasswordNeverExpires $true `
+ -PassThru
+Set-ADUser -Identity "$u" -ServicePrincipalNames @{Add="HTTP/web01"}
+Set-ADObject $u -Description "SPN on HTTP/web01"
+
+$genericAllUserSrc = Get-RandomObject -User
+$genericAllUserTgt = Get-RandomObject -User
+SetAcl $genericAllUserSrc $genericAllUserTgt "GenericAll" "None"
+Set-ADObject $genericAllUserSrc -Description "User with GenericAll rights over $($genericAllUserTgt.Name)"
+
+$genericAllDomainAdminsSrc = Get-RandomObject -User
+$domainAdminsGroup = Get-ADGroup "Domain Admins"
+SetAcl $genericAllDomainAdminsSrc $domainAdminsGroup "GenericAll" "None"
+Set-ADObject $genericAllDomainAdminsSrc -Description "User with GenericAll rights over Domain Admins group"
+
+$genericAllComputerSrc = Get-RandomObject -User
+$genericAllComputerTgt = Get-RandomObject -Computer
+SetAcl $genericAllComputerSrc $genericAllComputerTgt "GenericAll" "None"
+Set-ADObject $genericAllComputerSrc -Description "User with GenericAll rights over computer $($genericAllComputerTgt.Name)"
+
+$writePropertyDomainAdminsSrc = Get-RandomObject -User
+SetAcl $writePropertyDomainAdminsSrc $domainAdminsGroup "WriteProperty" "All"
+Set-ADObject $writePropertyDomainAdminsSrc -Description "User with WriteProperty rights over Domain Admins group (all properties)"
+
+$selfDomainAdminsSrc = Get-RandomObject -User
+SetAclExtended $selfDomainAdminsSrc $domainAdminsGroup "Self" "bf9679c0-0de6-11d0-a285-00aa003049e2" "None"
+Set-ADObject $selfDomainAdminsSrc -Description "User with Self membership control over Domain Admins group"
+
+$writePropertyExtDomainAdminsSrc = Get-RandomObject -User
+SetAclExtended $writePropertyExtDomainAdminsSrc $domainAdminsGroup "WriteProperty" "bf9679c0-0de6-11d0-a285-00aa003049e2" "All"
+Set-ADObject $writePropertyExtDomainAdminsSrc -Description "User with WriteProperty rights to modify Domain Admins group membership"
+
+$forceChangePwdSrc = Get-RandomObject -User
+$forceChangePwdTgt = Get-RandomObject -User
+SetAclExtended $forceChangePwdSrc $forceChangePwdTgt "ExtendedRight" "00299570-246d-11d0-a768-00aa006e0529" "None"
+Set-ADObject $forceChangePwdSrc -Description "User with ForceChangePassword rights over $($forceChangePwdTgt.Name)"
+
+$writeOwnerDomainAdminsSrc = Get-RandomObject -User
+SetAcl $writeOwnerDomainAdminsSrc $domainAdminsGroup "WriteOwner" "None"
+Set-ADObject $writeOwnerDomainAdminsSrc -Description "User with WriteOwner rights to take ownership of Domain Admins group"
+
+$genericWriteUserSrc = Get-RandomObject -User
+$genericWriteUserTgt = Get-RandomObject -User
+SetAcl $genericWriteUserSrc $genericWriteUserTgt "GenericWrite" "None"
+Set-ADObject $genericWriteUserSrc -Description "User with GenericWrite rights over $($genericWriteUserTgt.Name)"
+
+$writeDaclDomainAdminsSrc = Get-RandomObject -User
+SetAcl $writeDaclDomainAdminsSrc $domainAdminsGroup "WriteDacl" "None"
+Set-ADObject $writeDaclDomainAdminsSrc -Description "User with WriteDacl rights to modify Domain Admins group permissions"
+
+$asreproast_user = Get-RandomObject -User
+Set-ADAccountControl -Identity $asreproast_user -DoesNotRequirePreAuth $True
+Set-ADObject $asreproast_user -Description "DoesNotRequirePreAuth"
+
+$kerberoast_user = Get-RandomObject -User
+$kerberoast_spn = Get-RandomObject -Computer
+Set-ADUser -Identity "$kerberoast_user" -ServicePrincipalNames @{Add="HTTP/$($kerberoast_spn)"}
+Set-ADObject $kerberoast_user -Description "$($kerberoast_user | Select-Object -ExpandProperty Name) is kerberoastable on http/$($kerberoast_spn | Select-Object -ExpandProperty Name):80"
+
+$unconstrained_delegation_comp = Get-RandomObject -Computer
+$unconstrained_delegation_comp | Set-ADAccountControl -TrustedForDelegation $true
+Set-ADObject $unconstrained_delegation_comp -Description "TrustedForDelegation"
+
+$constrained_delegation_comp1 = Get-RandomObject -Computer
+$constrained_delegation_comp2 = Get-RandomObject -Computer
+Set-ADObject -Identity $constrained_delegation_comp1 -Add @{'msDS-AllowedToDelegateTo'=@("HOST/$($constrained_delegation_comp2)/example")}
+Set-ADAccountControl -Identity $constrained_delegation_comp1 -TrustedForDelegation $false -TrustedToAuthForDelegation $true
+Set-ADObject $constrained_delegation_comp1 -Description "msDS-AllowedToDelegateTo to $($constrained_delegation_comp2 | Select-Object -ExpandProperty Name)"
+
+Write-Host "[INFO] Created vulnerable ACLs, delegation, and Kerberos configurations"
+
+@"
+Domain content
+--------------
+"@ | Out-File C:\README.txt
+
+Get-AdObject `
+ -SearchBase "OU=$DomainOU,$DomainNameDN" `
+ -Filter {ObjectClass -ne "OrganizationalUnit"} `
+ -Properties Name, ObjectClass, Description `
+ | Select-Object Name, ObjectClass, Description `
+ | Format-Table -AutoSize `
+ | Out-File -Append C:\README.txt
+Stop-Transcript
diff --git a/ansible/scripts/setup-adcs-esc.ps1 b/ansible/scripts/setup-adcs-esc.ps1
new file mode 100644
index 0000000..44fc8d5
--- /dev/null
+++ b/ansible/scripts/setup-adcs-esc.ps1
@@ -0,0 +1,20 @@
+param (
+ [string]$DomainName = "contoso.com"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\$scriptName_log.txt"
+Start-Transcript -Path $logFile -Append
+
+Import-Module ADCSTemplate
+
+Get-ChildItem -Path "C:\setup\templates" -Filter *.json | % {
+ $TemplateName = $_.BaseName
+ if (-not(Get-ADCSTemplate -DisplayName $TemplateName)) {
+ New-ADCSTemplate `
+ -DisplayName $TemplateName `
+ -JSON (Get-Content "C:\setup\templates\$_" -Raw) `
+ -Identity "$DomainName\Domain Users" `
+ -Publish
+ }
+}
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/setup-adcs.ps1 b/ansible/scripts/setup-adcs.ps1
new file mode 100644
index 0000000..134b9a9
--- /dev/null
+++ b/ansible/scripts/setup-adcs.ps1
@@ -0,0 +1,50 @@
+param
+(
+ [string]$DomainName = "contoso.com",
+ [string]$Username = "Administrator",
+ [string]$Password = "packer"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+$p = ConvertTo-SecureString $Password -AsPlainText -Force
+$c = New-Object System.Management.Automation.PSCredential("$DomainName\$Username", $p)
+$CACommonName = "$($DomainName.Split(".")[0].ToUpper())-CA"
+
+try {
+ Install-WindowsFeature -Name AD-Certificate -IncludeAllSubFeature -IncludeManagementTools
+ Install-WindowsFeature -Name ADCS-Cert-Authority
+ Install-WindowsFeature -Name ADCS-Web-Enrollment
+ Install-WindowsFeature -Name RSAT
+
+ Write-Host "[INFO] Installed ADCS Windows Features"
+} catch {
+ Write-Host "[ERR] Failed to install ADCS Windows Features"
+}
+
+try {
+ Install-AdcsCertificationAuthority `
+ -Credential $c `
+ -CAType EnterpriseRootCA `
+ -CryptoProviderName "RSA#Microsoft Software Key Storage Provider" `
+ -KeyLength 2048 `
+ -HashAlgorithmName SHA256 `
+ -ValidityPeriod Years `
+ -ValidityPeriodUnits 5 `
+ -CACommonName $CACommonName `
+ -Force
+
+ Write-Host "[INFO] Installed ADCS Certification Authority"
+} catch {
+ Write-Host "[ERR] Failed to install ADCS Certification Authority"
+}
+
+try {
+ Install-AdcsWebEnrollment -Force
+
+ Write-Host "[INFO] Installed ADCS Web Enrollment"
+} catch {
+ Write-Host "[ERR] Failed to install ADCS Web Enrollment"
+}
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/setup-child-domain.ps1 b/ansible/scripts/setup-child-domain.ps1
new file mode 100644
index 0000000..ad23d45
--- /dev/null
+++ b/ansible/scripts/setup-child-domain.ps1
@@ -0,0 +1,50 @@
+param
+(
+ [string]$ParentDomainName = "contoso.com",
+ [string]$ChildDomainName = "dev",
+ [string]$SafeModePassword = "P4ssw0rd1234!",
+ [string]$Username = "Administrator",
+ [string]$Password = "packer"
+)
+
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+$p = ConvertTo-SecureString $Password -AsPlainText -Force
+$c = New-Object System.Management.Automation.PSCredential("$ParentDomainName\$Username", $p)
+
+Write-Host "[INFO] Setting Administrator password"
+$computerName = $env:COMPUTERNAME
+$adminPassword = $Password
+$adminUser = [ADSI] "WinNT://$computerName/Administrator,User"
+$adminUser.SetPassword($adminPassword)
+
+Write-Host "[INFO] Installing AD-Domain-Services feature"
+Install-WindowsFeature AD-Domain-Services -IncludeAllSubFeature -IncludeManagementTools
+
+Write-Host "[INFO] Importing ADDSDeployment module"
+Import-Module ADDSDeployment
+
+try {
+ Write-Host "[INFO] Installing New Child Domain in Existing Forest"
+ Install-ADDSDomain `
+ -InstallDns `
+ -ParentDomainName $ParentDomainName `
+ -NewDomainName $ChildDomainName `
+ -DomainType ChildDomain `
+ -DatabasePath "C:\Windows\NTDS" `
+ -LogPath "C:\Windows\NTDS" `
+ -SysvolPath "C:\Windows\SYSVOL" `
+ -NoRebootOnCompletion `
+ -Force `
+ -Credential $c `
+ -SafeModeAdministratorPassword (ConvertTo-SecureString -AsPlainText -Force "$SafeModePassword")
+
+ Write-Host "[INFO] Successfully added new child domain: $ChildDomainName"
+} catch {
+ Write-Host "[ERR] Failed to add new child domain: $ChildDomainName"
+ Write-Host $_.Exception.Message
+}
+
+Stop-Transcript
diff --git a/ansible/scripts/setup-gpo.ps1 b/ansible/scripts/setup-gpo.ps1
new file mode 100644
index 0000000..8d0bb5d
--- /dev/null
+++ b/ansible/scripts/setup-gpo.ps1
@@ -0,0 +1,29 @@
+param (
+ [string]$DomainName = "contoso.com"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+$DomainNameDN = "DC=$($DomainName.Split(".")[0]),DC=$($DomainName.Split(".")[1])"
+$DomainUsers = Get-ADGroup "Domain Users"
+try {
+ $GPO1 = New-GPO -Name "TestGPO1"
+ $GPO2 = New-GPO -Name "TestGPO2"
+ Set-GPPermission -Name $GPO1.DisplayName -PermissionLevel GpoEditDeleteModifySecurity -TargetName $DomainUsers.Name -TargetType Group
+ Set-GPPermission -Name $GPO2.DisplayName -PermissionLevel GpoEditDeleteModifySecurity -TargetName $DomainUsers.Name -TargetType Group
+
+ Write-Host "[INFO] Created insecure GPOs $($GPO1.DisplayName), $($GPO2.DisplayName) with GpoEditDeleteModifySecurity"
+} catch {
+ Write-Host "[ERR] Failed to create insecure GPOs $($GPO1.DisplayName), $($GPO2.DisplayName) with GpoEditDeleteModifySecurity"
+}
+
+try {
+ New-GPLink -Name $GPO1.DisplayName -Target "$DomainNameDN" -LinkEnabled Yes
+ New-GPLink -Name $GPO2.DisplayName -Target "$DomainNameDN" -LinkEnabled Yes
+
+ Write-Host "[INFO] Created GP links for $($GPO1.DisplayName), $($GPO2.DisplayName) on $DomainNameDN"
+} catch {
+ Write-Host "[ERR] Failed to create GP links for $($GPO1.DisplayName), $($GPO2.DisplayName) on $DomainNameDN"
+}
+Stop-Transcript
diff --git a/ansible/scripts/setup-iis.ps1 b/ansible/scripts/setup-iis.ps1
new file mode 100644
index 0000000..1bbe48d
--- /dev/null
+++ b/ansible/scripts/setup-iis.ps1
@@ -0,0 +1,128 @@
+ param
+(
+ [string]$DomainName = "contoso.com",
+ [string]$SvcUsername = "svc_iis03",
+ [string]$SvcPassword = "Svc1234!"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+$wwwroot1 = "C:\inetpub\wwwroot"
+$wwwroot2 = "C:\inetpub\wwwroot2"
+
+try {
+ Install-WindowsFeature -Name Web-Server -IncludeManagementTools
+ Install-WindowsFeature -Name Web-Asp-Net45
+ New-WebSite -Name "MyASPXSite" -Port 80 -PhysicalPath "C:\inetpub\wwwroot" -ApplicationPool "DefaultAppPool"
+ Set-ItemProperty "IIS:\AppPools\DefaultAppPool" -Name processModel -Value @{userName="$SvcUsername";password="$SvcPassword";identityType=3}
+ New-NetFirewallRule -DisplayName "HTTP (80)" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
+ Restart-WebAppPool -Name "DefaultAppPool"
+
+ Write-Host "[INFO] Created first IIS WebSite, Firewall rule and AppPool"
+} catch {
+ Write-Host "[ERR] Failed to create first IIS WebSite, Firewall rule and AppPool"
+}
+
+try {
+ $svcIIS03Rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$DomainName\$SvcUsername", "Modify", "ContainerInherit, ObjectInherit", "None", "Allow")
+ $acl = Get-Acl $wwwroot1
+ $acl.SetAccessRule($svcIIS03Rule)
+ Set-Acl -Path $wwwroot1 -AclObject $acl
+
+ Write-Host "[INFO] Set ACL for $wwwroot1"
+} catch {
+ Write-Host "[ERR] Failed to set ACL for $wwwroot1"
+}
+
+@"
+using System;
+using System.IO;
+using System.Web.UI;
+
+public partial class UploadPage : Page
+{
+ protected void UploadFile(object sender, EventArgs e)
+ {
+ if (fileUpload.PostedFile != null && fileUpload.PostedFile.ContentLength > 0)
+ {
+ try
+ {
+ string filename = Path.GetFileName(fileUpload.PostedFile.FileName);
+ fileUpload.PostedFile.SaveAs(Server.MapPath(filename));
+ lblMessage.Text = "File uploaded successfully!";
+ }
+ catch (Exception ex)
+ {
+ lblMessage.Text = "Error: " + ex.Message;
+ }
+ }
+ else
+ {
+ lblMessage.Text = "Please select a file to upload.";
+ }
+ }
+}
+"@ | Out-File C:\inetpub\wwwroot\upload.aspx.cs
+
+@"
+<%@ Page Language="C#" AutoEventWireup="true" CodeFile="upload.aspx.cs" Inherits="UploadPage" %>
+
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>File Upload Page</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ <input type="file" id="fileUpload" runat="server" />
+ <br />
+ <asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="UploadFile" />
+ <br />
+ <asp:Label ID="lblMessage" runat="server" Text=""></asp:Label>
+ </div>
+ </form>
+</body>
+</html>
+"@ | Out-File C:\inetpub\wwwroot\upload.aspx
+
+@"
+<?xml version="1.0"?>
+<configuration>
+ <system.web>
+ <compilation debug="true" targetFramework="4.5"/>
+ <httpRuntime targetFramework="4.5"/>
+ <customErrors mode="Off"/>
+ </system.web>
+</configuration>
+"@ | Out-File C:\inetpub\wwwroot\Web.config
+
+Restart-WebAppPool -Name "DefaultAppPool"
+
+try {
+ Copy-Item "C:\inetpub\wwwroot" -Destination "C:\inetpub\wwwroot2" -Recurse
+ New-WebAppPool -Name "DefaultAppPool2"
+ New-WebSite -Name "MyASPXSite2" -Port 8080 -PhysicalPath "C:\inetpub\wwwroot2" -ApplicationPool "DefaultAppPool2"
+ Set-ItemProperty "IIS:\AppPools\DefaultAppPool2" -Name processModel -Value @{ identityType=2 }
+ New-NetFirewallRule -DisplayName "HTTP (8080)" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow
+
+ Write-Host "[INFO] Created second IIS WebSite, Firewall rule and AppPool"
+} catch {
+ Write-Host "[ERR] Failed to create second IIS WebSite, Firewall rule and AppPool"
+}
+
+try {
+ $acl = Get-Acl $wwwroot2
+ $iisIUSRSGroup = "IIS_IUSRS"
+ $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", "Modify", "ContainerInherit, ObjectInherit", "None", "Allow")
+ $acl.SetAccessRule($rule)
+ Set-Acl -Path $wwwroot2 -AclObject $acl
+
+ Write-Host "[INFO] Set ACL for $wwwroot2"
+} catch {
+ Write-Host "[ERR] Failed to set ACL for $wwwroot2"
+}
+
+Restart-WebAppPool -Name "DefaultAppPool2"
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/setup-main-domain.ps1 b/ansible/scripts/setup-main-domain.ps1
new file mode 100644
index 0000000..75500ab
--- /dev/null
+++ b/ansible/scripts/setup-main-domain.ps1
@@ -0,0 +1,45 @@
+param
+(
+ [string]$DomainName = "contoso.com",
+ [string]$FunctionalLevel = "WinThreshold",
+ [string]$SafeModePassword = "P4ssw0rd1234!"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+$NetBiosName = $DomainName.Split(".")[0].ToUpper()
+
+Write-Host "[INFO] Setting Administrator password"
+$computerName = $env:COMPUTERNAME
+$adminPassword = "packer"
+$adminUser = [ADSI] "WinNT://$computerName/Administrator,User"
+$adminUser.SetPassword($adminPassword)
+
+Write-Host "[INFO] Installing Ad-Domain-Services Windows feature + subfeatures"
+Install-WindowsFeature AD-Domain-Services -IncludeAllSubFeature -IncludeManagementTools
+
+Write-Host "[INFO] Importing ADDSDeployment module"
+Import-Module ADDSDeployment
+
+try {
+ Write-Host "[INFO] Installing ADDSForest"
+ Install-ADDSForest `
+ -InstallDns `
+ -CreateDnsDelegation:$false `
+ -ForestMode $FunctionalLevel `
+ -DomainMode $FunctionalLevel `
+ -DomainName $DomainName `
+ -DomainNetbiosName $NetBiosName `
+ -DatabasePath "C:\Windows\NTDS" `
+ -LogPath "C:\Windows\NTDS" `
+ -SysvolPath "C:\Windows\SYSVOL" `
+ -NoRebootOnCompletion `
+ -Force `
+ -SafeModeAdministratorPassword (ConvertTo-SecureString -AsPlainText -Force "$SafeModePassword")
+ Write-Host "[INFO] Created Active Directory domain for $DomainName"
+} catch {
+ Write-Host "[ERR] Failed to create Active Directory domain for $DomainName"
+ Write-Host $_.Exception.Message
+}
+Stop-Transcript
diff --git a/ansible/scripts/setup-mssql-link.ps1 b/ansible/scripts/setup-mssql-link.ps1
new file mode 100644
index 0000000..8f51058
--- /dev/null
+++ b/ansible/scripts/setup-mssql-link.ps1
@@ -0,0 +1,18 @@
+param
+(
+ [string]$LinkServer = "mssql01"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+try {
+ SqlCmd -E -Q "EXEC master.dbo.sp_addlinkedserver @server = N'$LinkServer', @srvproduct=N'', @provider=N'SQLOLEDB', @datasrc=N'$LinkServer'"
+ SqlCmd -E -Q "EXEC master.dbo.sp_serveroption @server=N'$LinkServer', @optname=N'rpc', @optvalue=N'true'"
+ SqlCmd -E -Q "EXEC master.dbo.sp_serveroption @server=N'$LinkServer', @optname=N'rpc out', @optvalue=N'true'"
+ SqlCmd -E -Q "EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'$LinkServer', @locallogin = NULL , @useself = N'True'"
+ Write-Host "[INFO] Linked $LinkServer to mssql02"
+} catch {
+ Write-Host "[ERR] Failed to link $LinkServer to mssql02"
+}
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/setup-mssql.ps1 b/ansible/scripts/setup-mssql.ps1
new file mode 100644
index 0000000..032490f
--- /dev/null
+++ b/ansible/scripts/setup-mssql.ps1
@@ -0,0 +1,90 @@
+param
+(
+ [string]$DomainName = "contoso.com",
+ [string]$SvcUsername = "svc_mssql01",
+ [string]$SvcPassword = "Svc1234!"
+)
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+$NetBiosName = $DomainName.Split(".")[0].ToUpper()
+Start-Transcript -Path $logFile -Append
+
+New-Item -Path "C:\setup\media" -ItemType "Directory" -Force
+
+@"
+;SQL Server Configuration File
+[OPTIONS]
+IACCEPTSQLSERVERLICENSETERMS="True"
+ACTION="Install"
+ENU="True"
+QUIET="True"
+QUIETSIMPLE="False"
+UpdateEnabled="False"
+ERRORREPORTING="False"
+USEMICROSOFTUPDATE="False"
+FEATURES=SQLENGINE,FULLTEXT
+UpdateSource="MU"
+HELP="False"
+INDICATEPROGRESS="False"
+X86="False"
+INSTALLSHAREDDIR="C:\Program Files\Microsoft SQL Server"
+INSTALLSHAREDWOWDIR="C:\Program Files (x86)\Microsoft SQL Server"
+INSTANCENAME="SQLEXPRESS"
+SQMREPORTING="False"
+INSTANCEID="SQLEXPRESS"
+RSINSTALLMODE="DefaultNativeMode"
+INSTANCEDIR="C:\Program Files\Microsoft SQL Server"
+AGTSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE"
+AGTSVCSTARTUPTYPE="Automatic"
+COMMFABRICPORT="0"
+COMMFABRICNETWORKLEVEL="0"
+COMMFABRICENCRYPTION="0"
+MATRIXCMBRICKCOMMPORT="0"
+SQLSVCSTARTUPTYPE="Automatic"
+FILESTREAMLEVEL="0"
+ENABLERANU="False"
+SQLCOLLATION="SQL_Latin1_General_CP1_CI_AS"
+SQLSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE"
+SAPWD="$SvcPassword"
+SQLSYSADMINACCOUNTS="BUILTIN\Administrators"
+ADDCURRENTUSERASSQLADMIN="True"
+TCPENABLED="1"
+NPENABLED="0"
+BROWSERSVCSTARTUPTYPE="Disabled"
+RSSVCSTARTUPTYPE="manual"
+FTSVCACCOUNT="NT Service\MSSQLFDLauncher"
+"@ | Out-File "C:\setup\sql_conf.ini"
+
+try {
+ Start-Process -FilePath "C:\setup\SQL2019-SSEI-Expr.exe" -ArgumentList "/configurationfile=C:\setup\sql_conf.ini /IACCEPTSQLSERVERLICENSETERMS /MEDIAPATH=C:\setup\media /QUIET /HIDEPROGRESSBAR" -Wait
+ Write-Host "[INFO] Installed SQL Server Express"
+} catch {
+ Write-Host "[ERR] Failed to install SQL Server Express"
+}
+
+try {
+ Set-ItemProperty -Path "HKLM:\Software\Microsoft\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQLServer\SuperSocketNetLib\Tcp\IPAll" -Name "TcpPort" -Value "1433" -Force
+ Write-Host "[INFO] Set MSSQL port to 1433"
+} catch {
+ Write-Host "[ERR] Failed to set MSSQL port to 1433"
+}
+
+Restart-Service -Name "MSSQL`$SQLEXPRESS"
+
+try {
+ $env:Path += ";C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn"
+ SqlCmd -E -Q "CREATE LOGIN [$NetBiosName\$SvcUsername] FROM WINDOWS"
+ SqlCmd -E -Q "SP_ADDSRVROLEMEMBER '$NetBiosName\$SvcUsername', 'SYSADMIN'"
+
+ SqlCmd -E -Q "ALTER LOGIN sa ENABLE"
+ SqlCmd -E -Q "ALTER LOGIN sa WITH PASSWORD = '$SvcPassword', CHECK_POLICY=OFF"
+ Write-Host "[INFO] Added $NetBiosName\$SvcUsername as MSSQL login and sysadmin"
+ Write-Host "[INFO] Enabled SA login"
+} catch {
+ Write-Host "[ERR] Failed to add $NetBiosName\$SvcUsername as MSSQL login and sysadmin"
+ Write-Host "[ERR] Failed to enable SA login"
+
+}
+
+New-NetFirewallRule -DisplayName "SQLServer default instance" -Direction Inbound -LocalPort 1433 -Protocol TCP -Action Allow
+Stop-Transcript \ No newline at end of file
diff --git a/ansible/scripts/setup-tree-domain.ps1 b/ansible/scripts/setup-tree-domain.ps1
new file mode 100644
index 0000000..0f661a1
--- /dev/null
+++ b/ansible/scripts/setup-tree-domain.ps1
@@ -0,0 +1,50 @@
+param
+(
+ [string]$ParentForestRootDomain = "contoso.com",
+ [string]$NewTreeDomainName = "msp.org",
+ [string]$SafeModePassword = "P4ssw0rd1234!",
+ [string]$Username = "Administrator",
+ [string]$Password = "packer"
+)
+
+$scriptName = $MyInvocation.MyCommand.Name
+$logFile = "C:\Logs\${scriptName}_log.txt"
+Start-Transcript -Path $logFile -Append
+
+$p = ConvertTo-SecureString $Password -AsPlainText -Force
+$c = New-Object System.Management.Automation.PSCredential("$ParentForestRootDomain\$Username", $p)
+
+Write-Host "[INFO] Setting Administrator password"
+$computerName = $env:COMPUTERNAME
+$adminPassword = $Password
+$adminUser = [ADSI] "WinNT://$computerName/Administrator,User"
+$adminUser.SetPassword($adminPassword)
+
+Write-Host "[INFO] Installing AD-Domain-Services feature"
+Install-WindowsFeature AD-Domain-Services -IncludeAllSubFeature -IncludeManagementTools
+
+Write-Host "[INFO] Importing ADDSDeployment module"
+Import-Module ADDSDeployment
+
+try {
+ Write-Host "[INFO] Installing New Tree Domain in Existing Forest"
+ Install-ADDSDomain `
+ -InstallDns `
+ -ParentDomainName $ParentForestRootDomain `
+ -NewDomainName $NewTreeDomainName `
+ -DomainType TreeDomain `
+ -DatabasePath "C:\Windows\NTDS" `
+ -LogPath "C:\Windows\NTDS" `
+ -SysvolPath "C:\Windows\SYSVOL" `
+ -NoRebootOnCompletion `
+ -Force `
+ -Credential $c `
+ -SafeModeAdministratorPassword (ConvertTo-SecureString -AsPlainText -Force "$SafeModePassword")
+
+ Write-Host "[INFO] Successfully added new tree domain: $NewTreeDomainName"
+} catch {
+ Write-Host "[ERR] Failed to add new tree domain: $NewTreeDomainName"
+ Write-Host $_.Exception.Message
+}
+
+Stop-Transcript