Plan de Implantacion — Checklist por Fases
Generado con scripts/tenant_setup.py — tenant_plan.json
1
Configuracion Inicial del Tenant
Critico
Acceder al Admin Center
admin.microsoft.com
5 min
Completar asistente de configuracion
Perfil org, zona horaria Europe/Madrid
10 min
Configurar branding corporativo
Logo clinica, colores tema
15 min
2
Dominio Personalizado
Critico
Agregar dominio saludmediterranea.es
Desde el Admin Center > Configuracion
5 min
Verificar propiedad del dominio
Agregar TXT: MS=msXXXXXXXX en DNS
10 min + propagacion
Configurar 10 registros DNS
MX, TXT (SPF+DKIM), CNAME x6, SRV x2
20 min
3
Baseline de Seguridad
Critico
Habilitar Acceso Condicional + MFA
Primero en modo report-only 48h
15 min
Named location: sede Valencia
IP: 82.130.45.200/32
10 min
Habilitar registro de auditoria unificado
Obligatorio para GDPR sanitario
5 min
4
Configuracion de Servicios
Alta
Exchange Online
Buzon, flujo de correo, anti-spam
30 min
SharePoint + Teams + OneDrive
Politicas de intercambio, cuotas, permisos
60 min
5
Compliance GDPR + ENS
Alta
Configurar cumplimiento GDPR
Residencia de datos, politicas de retencion, flujos DSR para datos de pacientes
45 min
Aplicar recomendaciones ENS
Cifrado, controles de acceso, registros de auditoria para datos sanitarios
40 min
Registros DNS — saludmediterranea.es
10 registros generados automaticamente
Registro MX
| Tipo | Nombre | Valor | Prioridad |
|---|---|---|---|
| MX | @ | saludmediterranea-es.mail.protection.outlook.com | 0 |
Registros TXT (SPF + Verificacion)
| Tipo | Nombre | Valor |
|---|---|---|
| TXT | @ | v=spf1 include:spf.protection.outlook.com -all |
| TXT | @ | MS=msXXXXXXXX (reemplazar con valor real) |
Registros CNAME (6 registros)
| Nombre | Valor | Proposito |
|---|---|---|
| autodiscover | autodiscover.outlook.com | Autoconfig Outlook |
| selector1._domainkey | selector1-saludmediterranea-es._domainkey.onmicrosoft.com | DKIM (firmado) |
| selector2._domainkey | selector2-saludmediterranea-es._domainkey.onmicrosoft.com | DKIM (rotacion) |
| msoid | clientconfig.microsoftonline-p.net | Azure AD auth |
| enterpriseregistration | enterpriseregistration.windows.net | Registro dispositivos |
| enterpriseenrollment | enterpriseenrollment.manage.microsoft.com | MDM (Intune) |
Registros SRV (Teams/Skype)
| Nombre | Valor | Puerto | Prior. |
|---|---|---|---|
| _sip._tls | sipdir.online.lync.com | 443 | 100 |
| _sipfederationtls._tcp | sipfed.online.lync.com | 5061 | 100 |
Plan de Licencias Recomendado
48 usuarios — Distribucion optima para sector sanitario
Microsoft 365 E5
Gerentes + IT Admin
3
57,00 €/usuario/mes
Advanced Threat Protection
Azure AD P2 + PIM
Compliance avanzado
Microsoft 365 E3
Personal sanitario clinico
12
36,00 €/usuario/mes
Apps Office desktop
Azure AD P1 (Acceso Condicional)
Herramientas compliance GDPR
M365 Business Standard
Recepcion + Administracion
28
12,50 €/usuario/mes
Apps Office desktop
Teams + SharePoint + OneDrive
Exchange 50GB
M365 Business Basic
Personal auxiliar
5
6,00 €/usuario/mes
Teams + email
Apps Office (version web)
OneDrive 1TB
Coste mensual estimado
902 €
3xE5(171) + 12xE3(432) + 28xStd(350) + 5xBasic(30) + 48 usuarios
Coste anual
10.824 €
IVA no incluido
Usuarios a Provisionar — Muestra (9 de 48)
Script generado: create_users.ps1 — Validados: 9/9 is_valid: true
| Usuario | UPN | Departamento | Cargo | Licencia |
|---|---|---|---|---|
CG Carlos Garcia |
carlos.garcia@saludmediterranea.es | IT Administracion | IT Administrator | E5 |
MF Maria Fernandez |
maria.fernandez@saludmediterranea.es | Gerencia | Gerente General | E5 |
LN Luis Navarro |
luis.navarro@saludmediterranea.es | Gerencia | Director Medico | E5 |
AL Ana Lopez |
ana.lopez@saludmediterranea.es | Fisioterapia | Fisioterapeuta | E3 |
RS Roberto Sanchez |
roberto.sanchez@saludmediterranea.es | Odontologia | Dentista Principal | E3 |
PM Pilar Martinez |
pilar.martinez@saludmediterranea.es | Nutricion | Nutricionista | E3 |
ER Elena Ruiz |
elena.ruiz@saludmediterranea.es | Recepcion | Recepcionista Senior | Business Std |
MT Miguel Torres |
miguel.torres@saludmediterranea.es | Recepcion | Recepcionista | Business Std |
SI Sofia Iglesias |
sofia.iglesias@saludmediterranea.es | Administracion | Auxiliar Administrativo | Business Std |
Scripts PowerShell Generados
5 scripts listos para produccion — Revisados con -WhatIf antes de ejecutar
tenant_setup.ps1
create_users.ps1
offboard_ana_lopez.ps1
security_audit.ps1
ca_policy.ps1
# Microsoft 365 Tenant Initial Setup Script # Generated for: Clinica Salud Integral Mediterranea SL # Domain: saludmediterranea.es # Connect to Microsoft 365 services Write-Host "Connecting to Microsoft 365..." -ForegroundColor Cyan Connect-MgGraph -Scopes "Organization.ReadWrite.All", "Directory.ReadWrite.All", "Policy.ReadWrite.ConditionalAccess" Connect-ExchangeOnline Connect-MicrosoftTeams # Step 1: Configure organization settings Write-Host "Configuring organization settings..." -ForegroundColor Green $orgSettings = @{ DisplayName = "Clinica Salud Integral Mediterranea SL" PreferredLanguage = "es-ES" } Update-MgOrganization -OrganizationId (Get-MgOrganization).Id -BodyParameter $orgSettings # Step 2: Enable Security Defaults / Conditional Access Write-Host "Enabling MFA enforcement..." -ForegroundColor Green # Step 3: Enable audit logging (GDPR mandatory) Write-Host "Enabling unified audit log..." -ForegroundColor Green Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true Write-Host " Next: Add domain saludmediterranea.es and configure DNS records" -ForegroundColor Cyan Disconnect-MgGraph Disconnect-ExchangeOnline -Confirm:$false
# Bulk User Provisioning — saludmediterranea.es # Prerequisites: Microsoft.Graph + ExchangeOnlineManagement modules Connect-MgGraph -Scopes "User.ReadWrite.All", "Directory.ReadWrite.All" Connect-ExchangeOnline $users = @( @{ UserPrincipalName = "carlos.garcia@saludmediterranea.es" DisplayName = "Carlos Garcia"; GivenName = "Carlos"; Surname = "Garcia" JobTitle = "IT Administrator"; Department = "IT Administracion" LicenseSku = "SPE_E5"; UsageLocation = "ES" PasswordProfile = @{ Password = "ChangeMe@$(Get-Random -Minimum 1000 -Maximum 9999)"; ForceChangePasswordNextSignIn = $true } } @{ UserPrincipalName = "roberto.sanchez@saludmediterranea.es" DisplayName = "Roberto Sanchez"; GivenName = "Roberto"; Surname = "Sanchez" JobTitle = "Dentista Principal"; Department = "Odontologia" LicenseSku = "ENTERPRISEPACK"; UsageLocation = "ES" PasswordProfile = @{ Password = "ChangeMe@$(Get-Random -Minimum 1000 -Maximum 9999)"; ForceChangePasswordNextSignIn = $true } } # ... (48 usuarios totales en el script completo) ) foreach ($user in $users) { try { $newUser = New-MgUser -DisplayName $user.DisplayName ` -UserPrincipalName $user.UserPrincipalName ` -GivenName $user.GivenName -Surname $user.Surname ` -JobTitle $user.JobTitle -Department $user.Department ` -AccountEnabled -PasswordProfile $user.PasswordProfile ` -UsageLocation $user.UsageLocation Write-Host "Provisioned: $($user.UserPrincipalName)" -ForegroundColor Green } catch { Write-Warning "Failed $($user.UserPrincipalName): $_" } }
# User Offboarding — ana.lopez@saludmediterranea.es # Fisioterapeuta — Baja voluntaria 12/06/2026 Connect-MgGraph -Scopes "User.ReadWrite.All", "Directory.ReadWrite.All" Connect-ExchangeOnline $userEmail = "ana.lopez@saludmediterranea.es" $user = Get-MgUser -UserId $userEmail # Step 1: Block sign-in IMMEDIATELY Update-MgUser -UserId $user.Id -AccountEnabled $false Write-Host "✓ Account disabled" -ForegroundColor Green # Step 2: Revoke all active sessions (tokens) Revoke-MgUserSignInSession -UserId $user.Id Write-Host "✓ All sessions revoked" -ForegroundColor Green # Step 3: Remove from all groups $groups = Get-MgUserMemberOf -UserId $user.Id foreach ($group in $groups) { Remove-MgGroupMemberByRef -GroupId $group.Id -DirectoryObjectId $user.Id } # Step 4: Convert mailbox to shared (preserves patient emails) Set-Mailbox -Identity $userEmail -Type Shared Write-Host "✓ Mailbox converted to shared (GDPR: retencio 5 anos)" -ForegroundColor Green # Step 5: Auto-reply Set-MailboxAutoReplyConfiguration -Identity $userEmail ` -AutoReplyState Enabled ` -InternalMessage "Este buzon ya no esta activo. Contacte: recepcion@saludmediterranea.es" ` -ExternalMessage "Gracias por su mensaje. Para citas: +34 963 XXX XXX" # Step 6: Remove E3 license (902 EUR/mes saved: -36 EUR) $licenses = (Get-MgUserLicenseDetail -UserId $user.Id).SkuId Set-MgUserLicense -UserId $user.Id -AddLicenses @() -RemoveLicenses $licenses Write-Host "✓ Offboarding completado — Informe CSV generado" -ForegroundColor Green
# Microsoft 365 Security Audit — saludmediterranea.es # Checks: MFA, Admins, Inactive users, Permissions, Licenses # Output: CSV reports in SecurityAudit_YYYYMMDD_HHMMSS/ Connect-MgGraph -Scopes "Directory.Read.All", "User.Read.All", "AuditLog.Read.All" Connect-ExchangeOnline $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $reportPath = "SecurityAudit_$timestamp" New-Item -ItemType Directory -Path $reportPath -Force | Out-Null # [1/7] Check MFA Status for all 48 users Write-Host "[1/7] Checking MFA status..." -ForegroundColor Yellow $users = Get-MgUser -All -Property Id,DisplayName,UserPrincipalName,AccountEnabled foreach ($user in $users) { $authMethods = Get-MgUserAuthenticationMethod -UserId $user.Id $hasMFA = $authMethods.Count -gt 1 } # Export: SecurityAudit_XXXXXX/MFA_Status.csv # [2/7] Admin role audit Write-Host "[2/7] Auditing admin role assignments..." -ForegroundColor Yellow $adminRoles = Get-MgDirectoryRole -All # Export: AdminAccounts.csv # [3/7] Inactive users (>90 days) Write-Host "[3/7] Checking inactive users (90+ days)..." -ForegroundColor Yellow # Export: InactiveUsers.csv # [4/7] Conditional Access policies review Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State | Export-Csv -Path "$reportPath/CA_Policies.csv" -NoTypeInformation Write-Host "Audit complete. Reports in: $reportPath/" -ForegroundColor Green
# Conditional Access Policies — saludmediterranea.es # GDPR sanitario: MFA obligatorio para acceso a datos de pacientes Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess" # Policy 1: MFA para todos los usuarios (report-only primero) $mfaAllUsers = @{ DisplayName = "[CULTIVA] Require MFA - All Users" State = "enabledForReportingButNotEnforced" # Cambiar a 'enabled' tras 48h Conditions = @{ Users = @{ IncludeUsers = @("All") } } GrantControls = @{ Operator = "OR"; BuiltInControls = @("mfa") } } New-MgIdentityConditionalAccessPolicy -BodyParameter $mfaAllUsers # Policy 2: Bloquear autenticacion legacy (GDPR) $blockLegacy = @{ DisplayName = "[CULTIVA] Block Legacy Authentication" State = "enabled" Conditions = @{ ClientAppTypes = @("exchangeActiveSync", "other") } GrantControls = @{ Operator = "OR"; BuiltInControls = @("block") } } New-MgIdentityConditionalAccessPolicy -BodyParameter $blockLegacy # Policy 3: Named location Valencia (IP: 82.130.45.200/32) $namedLocation = @{ "@odata.type" = "#microsoft.graph.ipNamedLocation" DisplayName = "Sede Valencia - Clinica" IsTrusted = $true IpRanges = @(@{ "@odata.type" = "#microsoft.graph.iPv4CidrRange"; CidrAddress = "82.130.45.200/32" }) } New-MgIdentityConditionalAccessNamedLocation -BodyParameter $namedLocation Write-Host "✓ 3 politicas CA creadas. Revisar Sign-in logs en 48h antes de enforced."
Proceso de Offboarding — Ana Lopez
Fisioterapeuta · Baja voluntaria · 12/06/2026
1
Deshabilitar cuenta INMEDIATAMENTE
Bloquear inicio de sesion + revocar todos los tokens activos
Update-MgUser -UserId $user.Id -AccountEnabled $false
2
Revocar sesiones activas
Invalida todos los refresh tokens de M365, Teams, SharePoint
Revoke-MgUserSignInSession -UserId $user.Id
3
Eliminar de todos los grupos
Revoca acceso a carpetas de pacientes, canales Teams y sitios SharePoint
4
Convertir buzon a compartido
Preserva historial de emails (obligatorio GDPR sanitario 5 anos). Elimina necesidad de licencia E3.
Set-Mailbox -Identity $userEmail -Type Shared
5
Configurar respuesta automatica
Redirige pacientes a recepcion@saludmediterranea.es
6
Retirar licencia E3
Ahorro: 36 EUR/mes. Buzon compartido no requiere licencia activa.
Set-MgUserLicense -UserId $user.Id -RemoveLicenses $licenses
!
Accion pendiente: Archivar OneDrive (30 dias)
Asignar acceso al director medico. Tras 30 dias, valorar eliminacion permanente.
Seguridad + Compliance
GDPR + ENS — Sector sanitario
Security Audit Script
MFA, admins, inactivos, permisos, licencias — 7 checks
✓ security_audit.ps1
Acceso Condicional — 3 politicas
MFA All Users + Block Legacy Auth + Named Location Valencia
✓ ca_policy.ps1
Registro de Auditoria Unificado
Habilitado en setup — Logs de acceso a datos de pacientes
✓ Incluido en setup
GDPR Sanitario
Datos de pacientes — Reglamento 2016/679
Residencia de datos en UE configurada
Retencion de emails: 5 anos
Flujos DSR (derecho al olvido)
Audit log habilitado
MFA obligatorio
ENS — Nivel Medio
Esquema Nacional de Seguridad
Cifrado en transito y reposo
Cuentas admin separadas + PIM
Block Legacy Authentication
Named locations definidos
Secure Score revisado trimestral