Enforce SGU sign-in and session policies
This commit is contained in:
+12
-8
@@ -73,16 +73,20 @@ Every synchronized user also receives `Universidad La Salle` in the AD
|
|||||||
|
|
||||||
The generic SGU credential is rendered as a dedicated branded tile instead of
|
The generic SGU credential is rendered as a dedicated branded tile instead of
|
||||||
being grouped below the anonymous **Other user** tile. Machine policy assigns
|
being grouped below the anonymous **Other user** tile. Machine policy assigns
|
||||||
the SGU CLSID as the default provider while retaining the built-in Microsoft
|
the SGU CLSID as the default provider, hides the last signed-in identity, and
|
||||||
password provider. It enumerates one `CPFT_TILE_IMAGE` and places the
|
disables local-user enumeration while retaining the built-in Microsoft password
|
||||||
`CPFT_LARGE_TEXT` heading immediately after it with `CPFS_DISPLAY_IN_BOTH`,
|
provider and its **Other user** recovery path. It enumerates one
|
||||||
matching Microsoft's supported field ordering. LogonUI owns field typography:
|
`CPFT_TILE_IMAGE` and places the `CPFT_LARGE_TEXT` heading immediately after it
|
||||||
on Windows 10 and 11, the account-name title used by **Other user** is shell UI,
|
with `CPFS_DISPLAY_IN_SELECTED_TILE`. LogonUI owns field typography and vertical
|
||||||
not a style that a generic Credential Provider can request. Do not add a second
|
tile order: on Windows 10 and 11, the account-name title used by **Other user**
|
||||||
tile image or a synthetic Windows account to imitate that title.
|
is shell UI, not a style that a generic Credential Provider can request. Do not
|
||||||
|
add a second tile image, filter the system password provider, or create a
|
||||||
|
synthetic Windows account to imitate that title or ordering.
|
||||||
|
|
||||||
The managed hierarchy is rooted at `OU=Usuarios-SGU`: `Docentes`, `Alumnos`,
|
The managed hierarchy is rooted at `OU=Usuarios-SGU`: `Docentes`, `Alumnos`,
|
||||||
and `Administrativos` are direct child OUs beneath it.
|
and `Administrativos` are direct child OUs beneath it. The domain GPO
|
||||||
|
`SGU - User session restrictions` is linked to this root and enables the
|
||||||
|
per-user `DisableLockWorkstation` policy for the complete hierarchy.
|
||||||
|
|
||||||
Per-user synchronization is serialized inside the broker to prevent concurrent
|
Per-user synchronization is serialized inside the broker to prevent concurrent
|
||||||
create/reset races. Production deployments should run the broker as a gMSA with
|
create/reset races. Production deployments should run the broker as a gMSA with
|
||||||
|
|||||||
+38
-10
@@ -57,7 +57,8 @@ powershell.exe -NoProfile -ExecutionPolicy Bypass `
|
|||||||
Orden de la transacción:
|
Orden de la transacción:
|
||||||
|
|
||||||
1. instala .NET y los binarios versionados;
|
1. instala .NET y los binarios versionados;
|
||||||
2. registra COM y configura SGU como proveedor predeterminado;
|
2. registra COM, configura SGU como proveedor predeterminado y oculta el
|
||||||
|
último usuario que cerró sesión;
|
||||||
3. instala el guard de autorreparación;
|
3. instala el guard de autorreparación;
|
||||||
4. exige health mTLS del broker y ejecuta las comprobaciones locales;
|
4. exige health mTLS del broker y ejecuta las comprobaciones locales;
|
||||||
5. configura DNS del dominio;
|
5. configura DNS del dominio;
|
||||||
@@ -65,8 +66,25 @@ Orden de la transacción:
|
|||||||
7. al arrancar, el guard habilita RDP, NLA y WinRM y comprueba el estado final.
|
7. al arrancar, el guard habilita RDP, NLA y WinRM y comprueba el estado final.
|
||||||
|
|
||||||
La directiva de Windows **Assign a default credential provider** selecciona SGU
|
La directiva de Windows **Assign a default credential provider** selecciona SGU
|
||||||
por defecto. No se instala ningún filtro: el proveedor de contraseña de
|
por defecto. El instalador también habilita **Interactive logon: Don't display
|
||||||
Microsoft permanece disponible para cuentas creadas manualmente y recuperación.
|
last signed-in** y deshabilita **Enumerate local users on domain-joined
|
||||||
|
computers**. De este modo un usuario SGU desaparece después de cerrar sesión y
|
||||||
|
permanece el mosaico genérico **Other user**. No se instala ningún filtro: el
|
||||||
|
proveedor de contraseña de Microsoft permanece disponible para cuentas creadas
|
||||||
|
manualmente y recuperación.
|
||||||
|
|
||||||
|
En el controlador de dominio, aplicar una vez la directiva de usuario al árbol
|
||||||
|
completo `Usuarios-SGU`:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Set-SguDomainUserPolicies.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
El script crea y vincula de forma idempotente el GPO
|
||||||
|
`SGU - User session restrictions` y configura `DisableLockWorkstation=1` para
|
||||||
|
Administrativos, Alumnos y Docentes. La directiva elimina la acción manual de
|
||||||
|
bloqueo; no sustituye otras directivas independientes de protector de pantalla,
|
||||||
|
inactividad o desconexión de RDP.
|
||||||
|
|
||||||
## 3. Verificación y reparación
|
## 3. Verificación y reparación
|
||||||
|
|
||||||
@@ -82,21 +100,31 @@ Start-ScheduledTask -TaskName SGU-CredentialProvider-EnrollmentGuard
|
|||||||
```
|
```
|
||||||
|
|
||||||
Un resultado válido exige simultáneamente binario y registro COM, configuración,
|
Un resultado válido exige simultáneamente binario y registro COM, configuración,
|
||||||
certificados, .NET 10, proveedor SGU predeterminado y proveedor de contraseña de
|
certificados, .NET 10, proveedor SGU predeterminado, último usuario oculto,
|
||||||
Microsoft preservado. El script de reparación se encuentra en
|
enumeración local deshabilitada y proveedor de contraseña de Microsoft
|
||||||
|
preservado. El script de reparación se encuentra en
|
||||||
`C:\ProgramData\SGU\Enrollment` con ACL exclusiva para `SYSTEM` y
|
`C:\ProgramData\SGU\Enrollment` con ACL exclusiva para `SYSTEM` y
|
||||||
administradores.
|
administradores.
|
||||||
|
|
||||||
## 4. Experiencia de LogonUI
|
## 4. Experiencia de LogonUI
|
||||||
|
|
||||||
El proveedor usa un mosaico genérico dedicado, no una credencial asociada al SID
|
El proveedor usa un mosaico genérico dedicado, no una credencial asociada al SID
|
||||||
anónimo de **Other user**. Windows puede mostrar ahora la imagen institucional y
|
anónimo de **Other user**. Windows muestra la imagen institucional y la etiqueta
|
||||||
la etiqueta `Universidad La Salle · Acceso SGU`, además del encabezado
|
`Universidad La Salle · Acceso SGU`; el encabezado `Acceso institucional SGU`
|
||||||
`Acceso institucional SGU`. El orden visual exacto de los iconos de opciones lo
|
se publica como `CPFT_LARGE_TEXT` solamente en el mosaico seleccionado. LogonUI
|
||||||
decide Windows; lo administrable y exigido es cuál aparece seleccionado por
|
elige la familia, el peso y el tamaño final y no expone opciones de tipografía a
|
||||||
defecto.
|
un Credential Provider.
|
||||||
|
|
||||||
|
La configuración soportada garantiza que SGU queda seleccionado por defecto y
|
||||||
|
que no se conserva el último usuario. El orden vertical exacto de mosaicos lo
|
||||||
|
decide LogonUI y no tiene una directiva pública. Por seguridad no se filtra ni
|
||||||
|
se elimina **Other user**: Microsoft recomienda conservar al menos un proveedor
|
||||||
|
del sistema como ruta de recuperación.
|
||||||
|
|
||||||
Referencias de Microsoft:
|
Referencias de Microsoft:
|
||||||
|
|
||||||
- <https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-admx-credentialproviders#defaultcredentialprovider>
|
- <https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-admx-credentialproviders#defaultcredentialprovider>
|
||||||
|
- <https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-windowslogon#enumeratelocalusersondomainjoinedcomputers>
|
||||||
|
- <https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-admx-ctrlaltdel#disablelockcomputer>
|
||||||
|
- <https://learn.microsoft.com/en-us/windows/win32/api/credentialprovider/ne-credentialprovider-credential_provider_field_type>
|
||||||
- <https://learn.microsoft.com/en-us/windows/win32/api/credentialprovider/nf-credentialprovider-icredentialprovidercredential2-getusersid>
|
- <https://learn.microsoft.com/en-us/windows/win32/api/credentialprovider/nf-credentialprovider-icredentialprovidercredential2-getusersid>
|
||||||
|
|||||||
+12
-3
@@ -129,9 +129,18 @@ On Windows 10:
|
|||||||
-DotNetRuntimeInstallerPath C:\SGUDeploy\prerequisites\dotnet-runtime-10.0.11-win-x64.exe
|
-DotNetRuntimeInstallerPath C:\SGUDeploy\prerequisites\dotnet-runtime-10.0.11-win-x64.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
Use Lithnet's `Invoke-CredUI` test utility when available, or lock the VM and
|
Use Lithnet's `Invoke-CredUI` test utility when available, or sign out/restart
|
||||||
select **Acceso institucional SGU** under sign-in options. Keep the built-in
|
the VM and select **Acceso institucional SGU**. Keep the built-in Windows
|
||||||
Windows password tile visible.
|
password provider available through **Other user**.
|
||||||
|
|
||||||
|
On the domain controller, apply the SGU user policy once:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Set-SguDomainUserPolicies.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
It links `SGU - User session restrictions` to `OU=Usuarios-SGU` and prevents
|
||||||
|
managed users from manually locking the workstation.
|
||||||
|
|
||||||
Before testing through Hyper-V Enhanced Session/RDP, enable the dedicated lab
|
Before testing through Hyper-V Enhanced Session/RDP, enable the dedicated lab
|
||||||
group and Windows PowerShell Remoting:
|
group and Windows PowerShell Remoting:
|
||||||
|
|||||||
@@ -90,12 +90,13 @@ contenido. De esta forma se puede preparar una actualización aunque
|
|||||||
`LogonUI.exe` todavía tenga cargada la DLL anterior; el reinicio obligatorio
|
`LogonUI.exe` todavía tenga cargada la DLL anterior; el reinicio obligatorio
|
||||||
activa la nueva versión.
|
activa la nueva versión.
|
||||||
|
|
||||||
El instalador también asigna SGU como proveedor predeterminado mediante la
|
El instalador también asigna SGU como proveedor predeterminado, oculta el último
|
||||||
directiva de equipo de Windows. No modifica ni oculta el proveedor de contraseña
|
usuario que cerró sesión y deshabilita la enumeración de usuarios locales en el
|
||||||
de Microsoft.
|
equipo unido al dominio. No modifica ni oculta el proveedor de contraseña de
|
||||||
|
Microsoft; **Other user** permanece como ruta de recuperación.
|
||||||
|
|
||||||
Bloquear el equipo, abrir **Sign-in options** y elegir el icono azul con llave
|
Cerrar sesión o reiniciar el equipo. El acceso SGU debe quedar seleccionado por
|
||||||
del acceso SGU. El proveedor de contraseña de Microsoft debe permanecer visible.
|
defecto y el proveedor de contraseña de Microsoft debe permanecer disponible.
|
||||||
|
|
||||||
## 5. Verificación
|
## 5. Verificación
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ $settingsPath = Join-Path $env:ProgramData 'SGU\CredentialProvider\settings.json
|
|||||||
$providerRegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$providerClassId"
|
$providerRegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$providerClassId"
|
||||||
$classRegistryPath = "HKLM:\SOFTWARE\Classes\CLSID\$providerClassId\InprocServer32"
|
$classRegistryPath = "HKLM:\SOFTWARE\Classes\CLSID\$providerClassId\InprocServer32"
|
||||||
$defaultProviderPolicyPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System'
|
$defaultProviderPolicyPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System'
|
||||||
|
$interactiveLogonPolicyPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
|
||||||
|
|
||||||
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||||
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
|
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
|
||||||
@@ -181,13 +182,34 @@ if ($PSCmdlet.ShouldProcess($installPath, 'Install and register the SGU Credenti
|
|||||||
Set-Item -Path $providerRegistryPath -Value 'Universidad La Salle · Acceso SGU'
|
Set-Item -Path $providerRegistryPath -Value 'Universidad La Salle · Acceso SGU'
|
||||||
|
|
||||||
if (-not $DoNotSetAsDefaultCredentialProvider) {
|
if (-not $DoNotSetAsDefaultCredentialProvider) {
|
||||||
|
if (-not (Test-Path -LiteralPath $defaultProviderPolicyPath)) {
|
||||||
New-Item -Path $defaultProviderPolicyPath -Force | Out-Null
|
New-Item -Path $defaultProviderPolicyPath -Force | Out-Null
|
||||||
|
}
|
||||||
New-ItemProperty -Path $defaultProviderPolicyPath `
|
New-ItemProperty -Path $defaultProviderPolicyPath `
|
||||||
-Name DefaultCredentialProvider `
|
-Name DefaultCredentialProvider `
|
||||||
-Value $providerClassId `
|
-Value $providerClassId `
|
||||||
-PropertyType String `
|
-PropertyType String `
|
||||||
-Force | Out-Null
|
-Force | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Do not leave a signed-out SGU identity exposed as a persistent user tile.
|
||||||
|
# The Microsoft password provider remains registered and supplies Other user.
|
||||||
|
if (-not (Test-Path -LiteralPath $interactiveLogonPolicyPath)) {
|
||||||
|
New-Item -Path $interactiveLogonPolicyPath -Force | Out-Null
|
||||||
|
}
|
||||||
|
New-ItemProperty -Path $interactiveLogonPolicyPath `
|
||||||
|
-Name DontDisplayLastUserName `
|
||||||
|
-Value 1 `
|
||||||
|
-PropertyType DWord `
|
||||||
|
-Force | Out-Null
|
||||||
|
if (-not (Test-Path -LiteralPath $defaultProviderPolicyPath)) {
|
||||||
|
New-Item -Path $defaultProviderPolicyPath -Force | Out-Null
|
||||||
|
}
|
||||||
|
New-ItemProperty -Path $defaultProviderPolicyPath `
|
||||||
|
-Name EnumerateLocalUsers `
|
||||||
|
-Value 0 `
|
||||||
|
-PropertyType DWord `
|
||||||
|
-Force | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
$defaultProviderConfigured = $false
|
$defaultProviderConfigured = $false
|
||||||
@@ -207,5 +229,11 @@ catch {
|
|||||||
SettingsPath = $settingsPath
|
SettingsPath = $settingsPath
|
||||||
Registered = Test-Path -LiteralPath $providerRegistryPath
|
Registered = Test-Path -LiteralPath $providerRegistryPath
|
||||||
DefaultProviderConfigured = $defaultProviderConfigured
|
DefaultProviderConfigured = $defaultProviderConfigured
|
||||||
|
LastSignedInUserHidden = (Get-ItemPropertyValue `
|
||||||
|
-LiteralPath $interactiveLogonPolicyPath `
|
||||||
|
-Name DontDisplayLastUserName) -eq 1
|
||||||
|
LocalUserEnumerationDisabled = (Get-ItemPropertyValue `
|
||||||
|
-LiteralPath $defaultProviderPolicyPath `
|
||||||
|
-Name EnumerateLocalUsers) -eq 0
|
||||||
SystemPasswordProviderPreserved = $true
|
SystemPasswordProviderPreserved = $true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
[CmdletBinding(SupportsShouldProcess)]
|
||||||
|
param(
|
||||||
|
[string]$TargetOuDn = 'OU=Usuarios-SGU,DC=lci,DC=lasalle,DC=mx',
|
||||||
|
[string]$GpoName = 'SGU - User session restrictions',
|
||||||
|
[string]$DomainController = $env:COMPUTERNAME
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$policyKey = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System'
|
||||||
|
$policyValueName = 'DisableLockWorkstation'
|
||||||
|
|
||||||
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||||
|
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
|
||||||
|
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||||||
|
throw 'Run this script from an elevated Windows PowerShell session on a domain controller or management host.'
|
||||||
|
}
|
||||||
|
|
||||||
|
Import-Module ActiveDirectory -ErrorAction Stop
|
||||||
|
Import-Module GroupPolicy -ErrorAction Stop
|
||||||
|
|
||||||
|
$targetOu = Get-ADOrganizationalUnit `
|
||||||
|
-Identity $TargetOuDn `
|
||||||
|
-Server $DomainController `
|
||||||
|
-ErrorAction Stop
|
||||||
|
$domainDn = ($targetOu.DistinguishedName -split ',DC=', 2)[1]
|
||||||
|
if (-not $domainDn) {
|
||||||
|
throw 'TargetOuDn does not contain a domain distinguished name.'
|
||||||
|
}
|
||||||
|
$domainName = ($domainDn -replace ',DC=', '.')
|
||||||
|
|
||||||
|
$gpo = Get-GPO -Name $GpoName -Domain $domainName -Server $DomainController -ErrorAction SilentlyContinue
|
||||||
|
if (-not $gpo -and $PSCmdlet.ShouldProcess($GpoName, 'Create the SGU user policy GPO')) {
|
||||||
|
$gpo = New-GPO -Name $GpoName -Domain $domainName -Server $DomainController
|
||||||
|
}
|
||||||
|
if (-not $gpo) {
|
||||||
|
throw "The GPO '$GpoName' does not exist and was not created."
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingLink = @(Get-GPInheritance -Target $TargetOuDn -Domain $domainName -Server $DomainController).GpoLinks |
|
||||||
|
Where-Object DisplayName -eq $GpoName |
|
||||||
|
Select-Object -First 1
|
||||||
|
$existingLinkEnabled = $existingLink -and (
|
||||||
|
$existingLink.Enabled -eq $true -or
|
||||||
|
[string]$existingLink.Enabled -eq 'Yes')
|
||||||
|
if (-not $existingLink) {
|
||||||
|
if ($PSCmdlet.ShouldProcess($TargetOuDn, "Link and enable '$GpoName'")) {
|
||||||
|
New-GPLink `
|
||||||
|
-Name $GpoName `
|
||||||
|
-Target $TargetOuDn `
|
||||||
|
-Domain $domainName `
|
||||||
|
-Server $DomainController `
|
||||||
|
-LinkEnabled Yes | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (-not $existingLinkEnabled -and
|
||||||
|
$PSCmdlet.ShouldProcess($TargetOuDn, "Enable the '$GpoName' link")) {
|
||||||
|
Set-GPLink `
|
||||||
|
-Name $GpoName `
|
||||||
|
-Target $TargetOuDn `
|
||||||
|
-Domain $domainName `
|
||||||
|
-Server $DomainController `
|
||||||
|
-LinkEnabled Yes | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($PSCmdlet.ShouldProcess($GpoName, 'Prevent SGU users from manually locking workstations')) {
|
||||||
|
Set-GPRegistryValue `
|
||||||
|
-Name $GpoName `
|
||||||
|
-Domain $domainName `
|
||||||
|
-Server $DomainController `
|
||||||
|
-Key $policyKey `
|
||||||
|
-ValueName $policyValueName `
|
||||||
|
-Type DWord `
|
||||||
|
-Value 1 | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
$configuredValue = Get-GPRegistryValue `
|
||||||
|
-Name $GpoName `
|
||||||
|
-Domain $domainName `
|
||||||
|
-Server $DomainController `
|
||||||
|
-Key $policyKey `
|
||||||
|
-ValueName $policyValueName
|
||||||
|
$link = @(Get-GPInheritance -Target $TargetOuDn -Domain $domainName -Server $DomainController).GpoLinks |
|
||||||
|
Where-Object DisplayName -eq $GpoName |
|
||||||
|
Select-Object -First 1
|
||||||
|
$linkEnabled = $link -and (
|
||||||
|
$link.Enabled -eq $true -or
|
||||||
|
[string]$link.Enabled -eq 'Yes')
|
||||||
|
|
||||||
|
[pscustomobject]@{
|
||||||
|
GpoName = $GpoName
|
||||||
|
GpoId = $gpo.Id
|
||||||
|
TargetOu = $TargetOuDn
|
||||||
|
LinkEnabled = [bool]$linkEnabled
|
||||||
|
DisableLockWorkstation = [int]$configuredValue.Value
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ $providerRegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authent
|
|||||||
$passwordProviderRegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$passwordProviderClassId"
|
$passwordProviderRegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$passwordProviderClassId"
|
||||||
$classRegistryPath = "HKLM:\SOFTWARE\Classes\CLSID\$providerClassId\InprocServer32"
|
$classRegistryPath = "HKLM:\SOFTWARE\Classes\CLSID\$providerClassId\InprocServer32"
|
||||||
$defaultProviderPolicyPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System'
|
$defaultProviderPolicyPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System'
|
||||||
|
$interactiveLogonPolicyPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
|
||||||
$settingsPath = Join-Path $env:ProgramData 'SGU\CredentialProvider\settings.json'
|
$settingsPath = Join-Path $env:ProgramData 'SGU\CredentialProvider\settings.json'
|
||||||
$issues = [Collections.Generic.List[string]]::new()
|
$issues = [Collections.Generic.List[string]]::new()
|
||||||
|
|
||||||
@@ -51,6 +52,34 @@ if (-not $defaultProviderConfigured) {
|
|||||||
$issues.Add('The SGU provider is not assigned as the machine default credential provider.')
|
$issues.Add('The SGU provider is not assigned as the machine default credential provider.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$lastSignedInUserHidden = $false
|
||||||
|
try {
|
||||||
|
$lastSignedInUserHidden = (Get-ItemPropertyValue `
|
||||||
|
-LiteralPath $interactiveLogonPolicyPath `
|
||||||
|
-Name DontDisplayLastUserName `
|
||||||
|
-ErrorAction Stop) -eq 1
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
# Report the missing or unreadable policy as a failed enrollment check.
|
||||||
|
}
|
||||||
|
if (-not $lastSignedInUserHidden) {
|
||||||
|
$issues.Add('The last signed-in user is not hidden from LogonUI.')
|
||||||
|
}
|
||||||
|
|
||||||
|
$localUserEnumerationDisabled = $false
|
||||||
|
try {
|
||||||
|
$localUserEnumerationDisabled = (Get-ItemPropertyValue `
|
||||||
|
-LiteralPath $defaultProviderPolicyPath `
|
||||||
|
-Name EnumerateLocalUsers `
|
||||||
|
-ErrorAction Stop) -eq 0
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
# Report the missing or unreadable policy as a failed enrollment check.
|
||||||
|
}
|
||||||
|
if (-not $localUserEnumerationDisabled) {
|
||||||
|
$issues.Add('Local user enumeration is not explicitly disabled for the domain client.')
|
||||||
|
}
|
||||||
|
|
||||||
$passwordProviderPreserved = Test-Path -LiteralPath $passwordProviderRegistryPath
|
$passwordProviderPreserved = Test-Path -LiteralPath $passwordProviderRegistryPath
|
||||||
if (-not $passwordProviderPreserved) {
|
if (-not $passwordProviderPreserved) {
|
||||||
$issues.Add('The built-in Microsoft password provider registration is missing.')
|
$issues.Add('The built-in Microsoft password provider registration is missing.')
|
||||||
@@ -137,6 +166,8 @@ $result = [pscustomobject]@{
|
|||||||
ProviderBinary = $registeredDll
|
ProviderBinary = $registeredDll
|
||||||
ProviderBinaryPresent = [bool]$providerBinaryPresent
|
ProviderBinaryPresent = [bool]$providerBinaryPresent
|
||||||
DefaultProviderConfigured = $defaultProviderConfigured
|
DefaultProviderConfigured = $defaultProviderConfigured
|
||||||
|
LastSignedInUserHidden = $lastSignedInUserHidden
|
||||||
|
LocalUserEnumerationDisabled = $localUserEnumerationDisabled
|
||||||
PasswordProviderPreserved = $passwordProviderPreserved
|
PasswordProviderPreserved = $passwordProviderPreserved
|
||||||
SettingsPresent = [bool]$settings
|
SettingsPresent = [bool]$settings
|
||||||
ClientCertificatePresent = [bool]$clientCertificatePresent
|
ClientCertificatePresent = [bool]$clientCertificatePresent
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ public sealed class SguCredentialProvider : CredentialProviderBase
|
|||||||
ProviderTileIcon.Create());
|
ProviderTileIcon.Create());
|
||||||
yield return new LargeLabelControl(ControlKeys.Heading, "Acceso institucional SGU")
|
yield return new LargeLabelControl(ControlKeys.Heading, "Acceso institucional SGU")
|
||||||
{
|
{
|
||||||
State = FieldState.DisplayInBoth
|
// Isolate the CPFT_LARGE_TEXT heading from the compact provider tile
|
||||||
|
// for the selected-layout variant. LogonUI still owns the typography.
|
||||||
|
State = FieldState.DisplayInSelectedTile
|
||||||
};
|
};
|
||||||
yield return new SmallLabelControl(
|
yield return new SmallLabelControl(
|
||||||
ControlKeys.InformationLabel,
|
ControlKeys.InformationLabel,
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public sealed class ProviderTileIconTests
|
|||||||
SguCredentialTile tile = Assert.IsType<SguCredentialTile>(provider.CreateGenericTile());
|
SguCredentialTile tile = Assert.IsType<SguCredentialTile>(provider.CreateGenericTile());
|
||||||
|
|
||||||
Assert.Equal("Acceso institucional SGU", heading.Label);
|
Assert.Equal("Acceso institucional SGU", heading.Label);
|
||||||
Assert.Equal(FieldState.DisplayInBoth, heading.State);
|
Assert.Equal(FieldState.DisplayInSelectedTile, heading.State);
|
||||||
Assert.Equal(GenericTileDisplayMode.DisplayAsDedicatedTile, tile.GenericTileDisplayMode);
|
Assert.Equal(GenericTileDisplayMode.DisplayAsDedicatedTile, tile.GenericTileDisplayMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user