Classify SGU accounts into AD role groups
This commit is contained in:
@@ -31,6 +31,9 @@ param(
|
||||
[string]$BaseDn = 'DC=lci,DC=lasalle,DC=mx',
|
||||
[string]$DomainNetbios = 'LCI',
|
||||
[string]$UpnSuffix = 'lci.lasalle.mx',
|
||||
[string]$ProfessorGroupDn = '',
|
||||
[string]$StudentGroupDn = '',
|
||||
[string]$AdministrativeGroupDn = '',
|
||||
[string]$RemoteDesktopGroupDn = '',
|
||||
[ValidateLength(1, 64)]
|
||||
[string]$DefaultCompany = 'La Salle',
|
||||
@@ -72,10 +75,20 @@ if (-not $serverCertificate.Verify()) {
|
||||
throw 'The HTTPS server certificate chain is not trusted or is outside its validity period. Import the issuing CA chain; for a self-signed lab certificate, trust its public .cer in LocalMachine\Root.'
|
||||
}
|
||||
|
||||
Import-Module ActiveDirectory -ErrorAction Stop
|
||||
$usersOuName = 'Usuarios-SGU'
|
||||
$usersOuDn = "OU=$usersOuName,$BaseDn"
|
||||
if ([string]::IsNullOrWhiteSpace($ProfessorGroupDn)) {
|
||||
$ProfessorGroupDn = "CN=SGU-Docentes,$usersOuDn"
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($StudentGroupDn)) {
|
||||
$StudentGroupDn = "CN=SGU-Alumnos,$usersOuDn"
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($AdministrativeGroupDn)) {
|
||||
$AdministrativeGroupDn = "CN=SGU-Administrativos,$usersOuDn"
|
||||
}
|
||||
|
||||
if ($CreateMissingOus) {
|
||||
Import-Module ActiveDirectory -ErrorAction Stop
|
||||
$usersOuName = 'Usuarios-SGU'
|
||||
$usersOuDn = "OU=$usersOuName,$BaseDn"
|
||||
if (-not (Get-ADOrganizationalUnit -LDAPFilter "(ou=$usersOuName)" -SearchBase $BaseDn -SearchScope OneLevel -Server $LdapHost -ErrorAction SilentlyContinue)) {
|
||||
New-ADOrganizationalUnit -Name $usersOuName -Path $BaseDn -ProtectedFromAccidentalDeletion $true -Server $LdapHost | Out-Null
|
||||
}
|
||||
@@ -117,8 +130,41 @@ if ($CreateMissingOus) {
|
||||
}
|
||||
}
|
||||
|
||||
$roleGroupDefinitions = @(
|
||||
[pscustomobject]@{ Role = 'Professor'; Dn = $ProfessorGroupDn; Description = 'SGU accounts with the DO institutional prefix.' }
|
||||
[pscustomobject]@{ Role = 'Student'; Dn = $StudentGroupDn; Description = 'SGU accounts with the AL institutional prefix.' }
|
||||
[pscustomobject]@{ Role = 'Administrative'; Dn = $AdministrativeGroupDn; Description = 'SGU accounts with the AD institutional prefix.' }
|
||||
)
|
||||
foreach ($definition in $roleGroupDefinitions) {
|
||||
if (-not $definition.Dn.EndsWith(",$BaseDn", [StringComparison]::OrdinalIgnoreCase)) {
|
||||
throw "$($definition.Role)GroupDn must identify a security group beneath BaseDn."
|
||||
}
|
||||
|
||||
$roleGroup = Get-ADGroup -Identity $definition.Dn -Server $LdapHost -ErrorAction SilentlyContinue
|
||||
if (-not $roleGroup -and $CreateMissingOus) {
|
||||
$groupDnMatch = [regex]::Match($definition.Dn, '^CN=(?<Name>[^,]+),(?<Path>.+)$', [Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
||||
if (-not $groupDnMatch.Success) {
|
||||
throw "$($definition.Role)GroupDn must start with a simple CN component."
|
||||
}
|
||||
$groupName = $groupDnMatch.Groups['Name'].Value
|
||||
if ($groupName.Length -gt 20) {
|
||||
throw "$($definition.Role) group name exceeds the 20-character sAMAccountName limit."
|
||||
}
|
||||
New-ADGroup -Name $groupName -SamAccountName $groupName `
|
||||
-GroupCategory Security -GroupScope Global `
|
||||
-Path $groupDnMatch.Groups['Path'].Value `
|
||||
-Description $definition.Description -Server $LdapHost | Out-Null
|
||||
$roleGroup = Get-ADGroup -Identity $definition.Dn -Server $LdapHost -ErrorAction Stop
|
||||
}
|
||||
if (-not $roleGroup) {
|
||||
throw "The required $($definition.Role) security group does not exist: $($definition.Dn)"
|
||||
}
|
||||
if ($roleGroup.GroupCategory -ne 'Security') {
|
||||
throw "$($definition.Role)GroupDn must identify a security group."
|
||||
}
|
||||
}
|
||||
|
||||
if ($RemoteDesktopGroupDn) {
|
||||
Import-Module ActiveDirectory -ErrorAction Stop
|
||||
$remoteDesktopGroup = Get-ADGroup -Identity $RemoteDesktopGroupDn -Server $LdapHost -ErrorAction Stop
|
||||
if ($remoteDesktopGroup.GroupCategory -ne 'Security' -or
|
||||
-not $remoteDesktopGroup.DistinguishedName.EndsWith(",$BaseDn", [StringComparison]::OrdinalIgnoreCase)) {
|
||||
@@ -186,6 +232,9 @@ $productionSettings = @{
|
||||
ProfessorOuDn = "OU=Docentes,OU=Usuarios-SGU,$BaseDn"
|
||||
StudentOuDn = "OU=Alumnos,OU=Usuarios-SGU,$BaseDn"
|
||||
AdministrativeOuDn = "OU=Administrativos,OU=Usuarios-SGU,$BaseDn"
|
||||
ProfessorGroupDn = $ProfessorGroupDn
|
||||
StudentGroupDn = $StudentGroupDn
|
||||
AdministrativeGroupDn = $AdministrativeGroupDn
|
||||
RemoteDesktopGroupDn = $RemoteDesktopGroupDn
|
||||
DefaultCompany = $DefaultCompany
|
||||
CreateMissingOus = [bool]$CreateMissingOus
|
||||
|
||||
@@ -32,6 +32,7 @@ $eventNames = @{
|
||||
1300 = 'DirectorySynchronizationFailure'
|
||||
1301 = 'DirectoryOptionalMetadataFailure'
|
||||
1302 = 'DirectoryGroupMembershipFailure'
|
||||
1303 = 'DirectoryRoleGroupMembershipAdded'
|
||||
}
|
||||
|
||||
# Keep these reads unfiltered. Besides making archived and current logs behave
|
||||
|
||||
@@ -102,6 +102,7 @@ Bootstrap reproducible para el laboratorio SGU.
|
||||
- `sgu-server-bootstrap-$Version.zip`: crea el bosque AD/DNS, OUs, grupo RDP, GPO, recurso `Packages`, broker mTLS y administración remota; se reanuda solo después del reinicio.
|
||||
- `sgu-client-bootstrap-$Version.zip`: registra un certificado mTLS único, instala y valida el Credential Provider antes de unir el equipo al dominio, habilita RDP/WinRM y se repara al arranque.
|
||||
- `sgu-linux-client-bootstrap-$Version.zip`: une clientes Debian/Ubuntu o RHEL/Fedora/Rocky/AlmaLinux con realmd, Kerberos y SSSD. Solicita interactivamente la contraseña de unión y no instala el Credential Provider de Windows.
|
||||
- El Auth Broker clasifica sin tareas programadas cada cuenta autenticada: `AL` se agrega a `SGU-Alumnos`, `AD` a `SGU-Administrativos` y `DO` a `SGU-Docentes`; el bootstrap crea estos grupos de seguridad de forma idempotente.
|
||||
- El servidor configura WEF/WEC para registrar sesiones y fallos, inventariar el estado alcanzable de las máquinas cada cinco minutos y conservar durante 183 días tanto esos eventos como el diagnóstico estructurado del Auth Broker.
|
||||
- Windows Home se detecta y se rechaza con una explicación, ya que no admite unión a Active Directory ni RDP host.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user