Casos prácticos : Active Directory sin GUI#
Crea los siguientes clones enlazados:
Clon enlazado 1 de "Windows Server 2022 sin GUI" llamado WS22tunombre con IP 10.4.X.Y/8 o DHCP si es portátil y un nuevo adaptador de red para el servidor, conectado a una red interna con la dirección 172.16.0.10/16
Clon enlazado 2 de "Windows 11" llamado WC05tunombre con un adaptador a la red interna, le asignamos la dirección 172.16.0.15/16 con puerta de enlace 172.16.0.10 y DNS 172.16.0.10
Clon enlazado 3 de "Windows 11" llamado WC06tunombre con un adaptador a la red interna, le asignamos la dirección 172.16.0.16/16 con puerta de enlace 172.16.0.10 y DNS 172.16.0.10
Puedes ver la configuración en el siguiente vídeo
Configurar servicio de enrutamiento#
# Instalar el servicio de enrutamiento
Install-WindowsFeature Routing -IncludeManagementTools
# habilitar NAT para la red interna (se indica la red, no la IP del servidor)
New-NetNat -Name "NAT" -InternalIPInterfaceAddressPrefix "172.16.0.0/16"
# habilitamos el reenvío de paquetes
Set-NetIPInterface -Forwarding Enabled
Instalación y configuración de Active Directory y DNS#
Instalamos el rol de Servicio de dominio de Active Directory
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
Promocionamos el servidor como controlador de dominio
Import-Module ADDSDeployment
No tenemos creada ninguna parte de la infraestructura, comenzamos creando el bosque y se creará automáticamente el resto de la estructura
Install-ADDSForest
DomainName : tunombre.local
# la contraseña que pide (SafeModeAdministratorPassword) es la de DSRM,
# el modo de restauración de servicios de directorio
password : @lumn0
Puedes comprobar que se ha creado con el siguiente comando:
Get-ADComputer -Filter *
Unidades Organizativas, usuarios y grupos#
Vamos a crear las siguientes unidades organizativas:
New-ADOrganizationalUnit -DisplayName "DespachoX" -Name "DespachoX" -path "DC=tunombre,DC=local"
New-ADOrganizationalUnit -DisplayName "DespachoY" -Name "DespachoY" -path "DC=tunombre,DC=local"
Puedes comprobar las unidades creadas:
Get-ADOrganizationalUnit -LDAPFilter "(name=*)" | FT Name,DistinguishedName
En el caso de que necesites borrar una OU, recuerda que primero tienes que deshabilitar la protección contra el borrado accidental y luego borrarla
Set-ADOrganizationalUnit -Identity "OU=DespachoX,DC=tunombre,DC=local" -ProtectedFromAccidentalDeletion $False
Remove-ADOrganizationalUnit -Identity "OU=DespachoX,DC=tunombre,DC=local" -Recursive
Grupos y usuarios#
Vamos a crear los siguientes usuarios y grupos de seguridad
Grupo X
Usuario: tunombreX1 con la contraseña @lumn0X1, haz que sea miembro del grupo X
Usuario: tunombreX2 con la contraseña @lumn0X2, haz que sea miembro del grupo X
Grupo Y
Usuario: tunombreY1 con la contraseña @lumn0Y1, haz que sea miembro del grupo Y
Usuario: tunombreY2 con la contraseña @lumn0Y2, haz que sea miembro del grupo Y
New-ADGroup -DisplayName "X" -Name "X" -GroupScope DomainLocal -GroupCategory Security -Path "DC=tunombre,DC=local"
New-ADGroup -DisplayName "Y" -Name "Y" -GroupScope DomainLocal -GroupCategory Security -Path "DC=tunombre,DC=local"
Después creamos los usuarios, como se ve en el siguiente ejemplo con el usuario tunombreX1
New-ADUser -DisplayName "tunombreX1" -Name "tunombreX1" -UserPrincipalName "tunombreX1@tunombre.local" -Enabled:$True -Path "DC=tunombre,DC=local" -AccountPassword (ConvertTo-SecureString -string "@lumn0X1" -AsPlainText -Force) -ChangePasswordAtLogon:$False
Al establecer -ChangePasswordAtLogon:$False, estás indicando que no se requiere que el usuario cambie la contraseña la primera vez que inicia sesión. Si lo queremos cambiar sobre un usuario ya creado: Set-ADUser -Identity "tunombreX1" -ChangePasswordAtLogon $False. En el otro caso tendremos que iniciar la sesión al menos una vez para cambiar la contraseña, y hasta que no lo hagamos no podremos iniciar sesión por ssh.
Por último lo añadimos al grupo
Add-ADGroupMember -Identity "X" -Members "tunombreX1"
Podemos comprobar que se han creado los grupos y los usuarios:
Get-ADGroupMember "X" | Select-Object Name
Get-ADGroupMember "Y" | Select-Object Name
En el caso de que queramos cambiar la directiva de las contraseñas, por ejemplo hacer que tengan una menor complejidad para hacer pruebas:
# Ver la directiva de contraseñas actual
Get-ADDefaultDomainPasswordPolicy
# Deshabilitar los requisitos de complejidad
Set-ADDefaultDomainPasswordPolicy -Identity (Get-ADDomain).DistinguishedName -ComplexityEnabled $false
# le damos la nueva contraseña
Set-ADAccountPassword -Identity tunombreX1 -NewPassword (ConvertTo-SecureString "1234" -AsPlainText -Force) -Reset
Unir equipo al dominio#
Para añadir el equipo WC05tunombre al dominio, primero tendremos que cambiar el DNS y apuntar al Windows Server, luego en "Configuración/Sistema/Información/Dominio o grupo de trabajo" seleccionamos unir a dominio. En el caso de que el cliente no disponga de entorno gráfico:
# Comprobamos el DNS del cliente
Get-DnsClientServerAddress
# En el caso de que no apunte al servidor, lo cambiamos
# (el InterfaceIndex es el de tu adaptador, lo ves en el comando anterior):
Set-DnsClientServerAddress -InterfaceIndex 6 -ServerAddresses ("172.16.0.10", "8.8.8.8")
Por último lo metemos dentro del dominio con el siguiente comando que ejecutamos en el cliente; aparecerá un diálogo gráfico para introducir la contraseña
Add-Computer -DomainName "tunombre.local" -Credential tunombre\administrador -Restart -Force
# puedes comprobar que se ha añadido, ejecutando en el servidor
Get-ADComputer -Filter * | FT Name
En el caso de que quieras hacerlo sin diálogo gráfico (por ejemplo, en una conexión por ssh):
$password = ConvertTo-SecureString "@lumn0" -AsPlainText -Force
$credenciales = New-Object System.Management.Automation.PSCredential("tunombre\administrador", $password)
Add-Computer -DomainName "tunombre.local" -Credential $credenciales -Restart -Force
Es posible que al clonar los equipos, puedan surgir problemas debido a que comparten el mismo SID. Para solucionarlo:
Si queremos sacar la máquina del dominio:
# en el cliente (lo saca del dominio y lo devuelve a un grupo de trabajo):
Remove-Computer -UnjoinDomainCredential tunombre\administrador -Restart -Force
# en el servidor (borra la cuenta del equipo del directorio):
Remove-ADComputer -Identity "WC06TUNOMBRE"
En Windows, puedes utilizar el siguiente comando para sincronizar la hora con un servidor de tiempo en línea:
w32tm /resync
#darla a mano:
Set-Date -Date "lunes, 6 de mayo de 2024 9:27:57"
Carpeta compartida#
Creamos una carpeta en el servidor
C:\XY-TUNOMBRE
├───X-tunombre
└───Y-tunombre
y la compartimos:
New-SmbShare -Name "X" -Path "C:\XY-TUNOMBRE\X-tunombre" -FullAccess "X", "Administradores"
Name ScopeName Path Description
---- --------- ---- -----------
X * C:\XY-TUNOMBRE\X-tunombre
Podemos comprobar las carpetas que hay compartidas, ejecutando en el servidor:
net share
Para acceder a ellas:
# Podemos ver que está en:
ls "\\WS22TUNOMBRE\X"
# Podemos montarla en el cliente en la unidad X:
New-PSDrive -Name "X" -PSProvider "FileSystem" -Root "\\WS22TUNOMBRE\X"
Utilizando el entorno gráfico
Para dejar de compartir la carpeta:
net share NombreRecurso /delete
Administración remota#
WinRM (Windows Remote Management) es un conjunto de servicios de administración remota que permite a los administradores de sistemas administrar y ejecutar comandos en sistemas Windows de forma remota, utiliza el protocolo WS-Management (WSMan) para establecer conexiones remotas y ejecutar comandos de manera segura.
Para permitir la administración remota del cliente, configuramos WinRM:
winrm quickconfig
Desde el servidor podemos ejecutar comandos:
Invoke-Command -ComputerName WC05TUNOMBRE,WC06TUNOMBRE -ScriptBlock {HOSTNAME.EXE}
Invoke-Command se comunica con hasta 32 equipos a la vez; si ponemos más, los siguientes esperarán a que terminen los 32 primeros.
Si queremos abrir una sesión
Enter-PSSession WC06TUNOMBRE
Exit-PSSession
También ofrece la opción de crear una conexión persistente ("PSSession"), en la que las re-conexiones son mucho más rápidas y se conserva el estado. Para ello creamos la sesión con New-PSSession y, en lugar de usar -ComputerName con Enter-PSSession o Invoke-Command, utilizaremos su parámetro -Session pasándole el objeto PSSession existente y abierto. Esto permite a los comandos volver a utilizar la conexión persistente que se había creado anteriormente.
# Crear una nueva sesión remota
$session = New-PSSession -ComputerName WC06TUNOMBRE
# Ejecutar un comando en la sesión remota
Invoke-Command -Session $session -ScriptBlock { Get-PSSessionConfiguration }
# Habilitar la ejecución de scripts en los equipos
Invoke-Command -Session $session -ScriptBlock { Set-ExecutionPolicy Unrestricted }
# Podemos instalar el servidor ssh de forma remota:
Invoke-Command -Session $session -ScriptBlock { Add-WindowsCapability -Online -Name $(Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.server*' | Select-Object Name| Select-Object -Index 0) }
Invoke-Command -Session $session -ScriptBlock { Get-Service sshd }
Como la sesión se mantiene y se reutiliza, el estado se conserva entre llamadas:
Invoke-Command -Session $session -ScriptBlock { $a = 1 }
Invoke-Command -Session $session -ScriptBlock { echo $a }
1
Podemos cargar un script:
$scriptBlock = {
echo "hola $(whoami.exe)"
echo "hoy es $(date)"
}
Invoke-Command -Session $session -ScriptBlock $scriptBlock
También podemos cargarlo de un archivo, para editar el script lo podemos hacer directamente con el editor vim utilizando una conexión por ssh
PS C:\Users\Administrador> cat script.ps1
echo "hola $(whoami.exe)"
echo "hoy es $(date)"
PS C:\Users\Administrador> Invoke-Command -FilePath script.ps1 -Session $session
hola tunombre\administrador
hoy es 05/06/2024 10:52:12
Para tener acceso a un recurso compartido de red en una sesión remota (por defecto la sesión remota no puede reutilizar nuestras credenciales contra un tercer equipo, es el llamado problema del doble salto), utilizamos Enable-WSManCredSSP, que sirve para habilitar la delegación de credenciales de CredSSP (Credential Security Support Provider) en el servidor de administración remota y en el cliente.
Enable-WSManCredSSP -Role client -DelegateComputer WC06TUNOMBRE
# usamos la $session creada
Invoke-Command -Session $session -ScriptBlock { Enable-WSManCredSSP -Role Server -Force }
$parameters = @{
ComputerName = 'WC06TUNOMBRE'
ScriptBlock = { Get-Item \\WS22tunombre\sysvol\tunombre.local\scripts\mount.ps1 }
Authentication = 'CredSSP'
Credential = 'tunombre\Administrador'
}
Invoke-Command @parameters
Ten en cuenta que necesitarás acceso al entorno gráfico:
De esta forma podemos instalar programas que se encuentren en una carpeta compartida
Invoke-Command -Credential tunombre\Administrador -ComputerName WC06TUNOMBRE -Authentication CredSSP -ScriptBlock {Start-Process msiexec.exe -ArgumentList "/i \\WS22tunombre\sysvol\tunombre.local\vlc-3.0.20-win64.msi /qn" -Wait}
Sería lo mismo que:
$parameters = @{
Credential = 'tunombre\Administrador'
ComputerName = 'WC06TUNOMBRE'
Authentication = 'CredSSP'
ScriptBlock = {
param($dirmsi)
Start-Process msiexec.exe -ArgumentList "/i $dirmsi /qn" -Wait
}
ArgumentList = '\\WS22tunombre\sysvol\tunombre.local\vlc-3.0.20-win64.msi'
}
Invoke-Command @parameters
Mapear unidades de red a las carpetas compartidas#
cat \\WS22tunombre\sysvol\tunombre.local\scripts\mount.ps1
New-PSDrive -Name "X" -PSProvider "FileSystem" -Root "\\WS22TUNOMBRE\X"
En el caso que queramos que el cambio sea permanente:
New-PSDrive -Persist -Name "X" -PSProvider "FileSystem" -Root "\\WS22TUNOMBRE\X" -Scope Global
Mover objetos entre las diferentes unidades organizativas#
Vamos a mover un equipo de Computers a DespachoX, primero vemos los clientes que tenemos:
Get-ADComputer -Filter * | Select-Object Name, DistinguishedName
# Nuestro cliente está en:
Get-ADComputer -Filter {Name -eq "WC06TUNOMBRE"} | FT DistinguishedName
Vemos las siguientes unidades organizativas:
#Tenemos las siguientes unidades organizativas
Get-ADOrganizationalUnit -Filter * -SearchBase "DC=tunombre,DC=local" | FT DistinguishedName
Movemos el equipo al "DespachoX"
$IdentidadEquipo = $(Get-ADComputer -Identity "WC06TUNOMBRE").DistinguishedName
Move-ADObject -Identity $IdentidadEquipo -TargetPath "OU=DespachoX,DC=tunombre,DC=local" -Confirm:$False
Crear y vincular GPO#
Creamos la política de grupo:
New-GPO -Name "MapearX"
Asignar la configuración de inicio de sesión a la GPO. La clave Run del registro ejecuta lo que tenga como valor cada vez que se inicia sesión; como un .ps1 no es directamente ejecutable, lo lanzamos a través de powershell.exe:
$parameters = @{
Name = 'MapearX'
Key = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
ValueName = "ScriptName"
Type = "String"
Value = "powershell.exe -ExecutionPolicy Bypass -File \\WS22tunombre\sysvol\tunombre.local\scripts\mount.ps1"
}
Set-GPRegistryValue @parameters
La vinculamos:
Get-GPO -Name "MapearX" | New-GPLink -Target "OU=DespachoX,DC=tunombre,DC=local"
Si queremos desvincular:
Remove-GPLink -Name <Nombre> -Target <Path_OU_Dominio>
Borrarla:
Remove-GPO -Name <Nombre> -Domain <dominio>
Gestión de ACL sin entorno gráfico#
Access Control List o "Lista de Control de Acceso" se utiliza para definir y controlar los permisos de acceso a recursos, como archivos, carpetas, impresoras y otros objetos en un sistema informático (ver Permisos NTFS y carpetas compartidas). Con el comando Get-Acl podemos obtener la ACL de un archivo o carpeta.
PS C:\Users> Get-Acl A
Path Owner Access
---- ----- ------
A BUILTIN\Administradores NT AUTHORITY\SYSTEM Allow FullControl...
PS C:\Users> $(Get-Acl A).Owner
BUILTIN\Administradores
PS C:\Users> $(Get-Acl A).Group
TUNOMBRE\Ninguno
Con el comando icacls puedes administrar las Listas de Control de Acceso (ACLs) en archivos y carpetas.
# Cambiar permisos en un archivo o carpeta:
PS C:\Users> icacls A /grant "tunombre\tunombreX1:(OI)(CI)RW"
PS C:\Users> Get-Acl A
Path Owner Access
---- ----- ------
A BUILTIN\Administradores TUNOMBRE\tunombreX1 Allow Write, Read, Synchronize...
# le hemos dado permisos de RW al usuario tunombreX1
# Para cambiar propietario
icacls A /setowner "tunombre\tunombreX1"
Ejemplo de cómo dar permisos de RW a un grupo completo:
$permissions = "Read", "Write"
$acl = Get-Acl -Path A
# Crear una regla de acceso para el grupo X
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("X", $permissions, "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.SetAccessRule($accessRule)
Set-Acl -Path A -AclObject $acl
Otro ejemplo, vamos a crear una carpeta llamada 'XY' y dentro dos subcarpetas llamadas 'X' y 'Y'. Definiremos los permisos para que solo el grupo 'X' tenga acceso de entrada a la carpeta 'X' dentro de 'XY'.
Creamos las carpetas:
# si existía de antes, la borramos
rm -r C:\Users\XY
mkdir C:\Users\XY
mkdir C:\Users\XY\X
mkdir C:\Users\XY\Y
Obtenemos el objeto ACL actual de la carpeta XY
$acl= Get-Acl -Path "C:\Users\XY"
Damos permisos para la carpeta principal (lectura y listar el contenido)
$permisos= "ReadAndExecute", "ListDirectory"
Creamos las reglas de acceso para los grupos X e Y
$reglaX = New-Object System.Security.AccessControl.FileSystemAccessRule("X",$permisos, "Allow")
$reglaY = New-Object System.Security.AccessControl.FileSystemAccessRule("Y",$permisos, "Allow")
Agregamos las reglas de acceso a la carpeta "XY"
$acl.AddAccessRule($reglaX)
$acl.AddAccessRule($reglaY)
Set-Acl -Path "C:\Users\XY" -AclObject $acl
Agregamos permisos para que la carpeta "X" pueda ser modificada por el grupo "X"
cd C:\Users\XY
$acl= Get-Acl -Path "C:\Users\XY\X"
$permisos = "Modify"
$regla = New-Object System.Security.AccessControl.FileSystemAccessRule("X",$permisos, "Allow")
$acl.AddAccessRule($regla)
Set-Acl -Path "C:\Users\XY\X" -AclObject $acl
Agregamos permisos para que la carpeta "Y" pueda ser modificada por el grupo "Y"
$acl= Get-Acl -Path "C:\Users\XY\Y"
$permisos = "Modify"
$regla = New-Object System.Security.AccessControl.FileSystemAccessRule("Y",$permisos, "Allow")
$acl.AddAccessRule($regla)
Set-Acl -Path "C:\Users\XY\Y" -AclObject $acl