Add branded default provider and enforced enrollment
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[switch]$RequireDomainJoined,
|
||||
[switch]$RequireRemoteAccess,
|
||||
[switch]$RequireBrokerHealth,
|
||||
[string]$RemoteDesktopPrincipal = 'LCI\SG-Laboratorio-Usuarios-RDP',
|
||||
[switch]$Enforce
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$providerClassId = '{D789CFD8-5AD4-489F-9B83-7EB5D9D09335}'
|
||||
$passwordProviderClassId = '{60B78E88-EAD8-445C-9CFD-0B87F74EA6CD}'
|
||||
$providerRegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$providerClassId"
|
||||
$passwordProviderRegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$passwordProviderClassId"
|
||||
$classRegistryPath = "HKLM:\SOFTWARE\Classes\CLSID\$providerClassId\InprocServer32"
|
||||
$defaultProviderPolicyPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System'
|
||||
$settingsPath = Join-Path $env:ProgramData 'SGU\CredentialProvider\settings.json'
|
||||
$issues = [Collections.Generic.List[string]]::new()
|
||||
|
||||
$computer = Get-CimInstance Win32_ComputerSystem
|
||||
if ($RequireDomainJoined -and -not $computer.PartOfDomain) {
|
||||
$issues.Add('The computer is not joined to a domain.')
|
||||
}
|
||||
|
||||
$providerRegistered = Test-Path -LiteralPath $providerRegistryPath
|
||||
if (-not $providerRegistered) {
|
||||
$issues.Add('The SGU Credential Provider registration is missing.')
|
||||
}
|
||||
|
||||
$registeredDll = $null
|
||||
if (Test-Path -LiteralPath $classRegistryPath) {
|
||||
$registeredDll = (Get-Item -LiteralPath $classRegistryPath).GetValue('')
|
||||
}
|
||||
$providerBinaryPresent = $registeredDll -and (Test-Path -LiteralPath $registeredDll -PathType Leaf)
|
||||
if (-not $providerBinaryPresent) {
|
||||
$issues.Add('The registered SGU COM binary is missing.')
|
||||
}
|
||||
|
||||
$configuredDefault = $null
|
||||
try {
|
||||
$configuredDefault = Get-ItemPropertyValue `
|
||||
-LiteralPath $defaultProviderPolicyPath `
|
||||
-Name DefaultCredentialProvider `
|
||||
-ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
# Report the missing or unreadable policy as a failed enrollment check.
|
||||
}
|
||||
$defaultProviderConfigured = $configuredDefault -eq $providerClassId
|
||||
if (-not $defaultProviderConfigured) {
|
||||
$issues.Add('The SGU provider is not assigned as the machine default credential provider.')
|
||||
}
|
||||
|
||||
$passwordProviderPreserved = Test-Path -LiteralPath $passwordProviderRegistryPath
|
||||
if (-not $passwordProviderPreserved) {
|
||||
$issues.Add('The built-in Microsoft password provider registration is missing.')
|
||||
}
|
||||
|
||||
$settings = $null
|
||||
try {
|
||||
$settings = Get-Content -LiteralPath $settingsPath -Raw | ConvertFrom-Json
|
||||
}
|
||||
catch {
|
||||
$issues.Add('The SGU provider settings file is missing or invalid.')
|
||||
}
|
||||
|
||||
$clientCertificatePresent = $false
|
||||
$serverCertificateTrusted = $false
|
||||
$brokerHealth = $null
|
||||
if ($settings) {
|
||||
$clientCertificate = Get-ChildItem Cert:\LocalMachine\My |
|
||||
Where-Object Thumbprint -eq $settings.ClientCertificateThumbprint |
|
||||
Select-Object -First 1
|
||||
$clientCertificatePresent = $clientCertificate -and $clientCertificate.HasPrivateKey
|
||||
if (-not $clientCertificatePresent) {
|
||||
$issues.Add('The client mTLS certificate with private key is missing.')
|
||||
}
|
||||
|
||||
$serverCertificate = Get-ChildItem Cert:\LocalMachine\Root,Cert:\LocalMachine\CA |
|
||||
Where-Object Thumbprint -eq $settings.ServerCertificateThumbprint |
|
||||
Select-Object -First 1
|
||||
$serverCertificateTrusted = [bool]$serverCertificate
|
||||
if (-not $serverCertificateTrusted) {
|
||||
$issues.Add('The broker certificate is not trusted by LocalMachine.')
|
||||
}
|
||||
|
||||
if ($RequireBrokerHealth -and $clientCertificatePresent) {
|
||||
try {
|
||||
$healthUri = ([Uri]$settings.BrokerEndpoint).GetLeftPart([UriPartial]::Authority) + '/health/live'
|
||||
$health = Invoke-RestMethod -Uri $healthUri -Certificate $clientCertificate -TimeoutSec 10
|
||||
$brokerHealth = [string]$health.status
|
||||
if ($brokerHealth -ne 'ok') {
|
||||
$issues.Add('The broker health endpoint did not return ok.')
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$issues.Add("The broker health check failed: $($_.Exception.Message)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dotNetRuntimePresent = $false
|
||||
$dotnetCandidates = @(
|
||||
(Get-Command dotnet -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source -ErrorAction SilentlyContinue),
|
||||
(Join-Path $env:ProgramFiles 'dotnet\dotnet.exe')
|
||||
) | Where-Object { $_ -and (Test-Path -LiteralPath $_ -PathType Leaf) } | Select-Object -Unique
|
||||
foreach ($dotnet in $dotnetCandidates) {
|
||||
if (& $dotnet --list-runtimes | Select-String '^Microsoft\.NETCore\.App 10\.') {
|
||||
$dotNetRuntimePresent = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (-not $dotNetRuntimePresent) {
|
||||
$issues.Add('The Microsoft .NET 10 x64 runtime is missing.')
|
||||
}
|
||||
|
||||
$remoteAccessReady = $null
|
||||
if ($RequireRemoteAccess) {
|
||||
$remoteDesktopUsersSid = [Security.Principal.SecurityIdentifier]::new('S-1-5-32-555')
|
||||
$remoteDesktopUsersGroup = ($remoteDesktopUsersSid.Translate([Security.Principal.NTAccount]).Value -split '\\', 2)[1]
|
||||
$rdpMembers = @(Get-LocalGroupMember -Group $remoteDesktopUsersGroup -ErrorAction SilentlyContinue)
|
||||
$remoteAccessReady =
|
||||
(Get-Service TermService).Status -eq 'Running' -and
|
||||
(Get-Service WinRM).Status -eq 'Running' -and
|
||||
(Get-ItemPropertyValue 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections) -eq 0 -and
|
||||
$rdpMembers.Name -contains $RemoteDesktopPrincipal
|
||||
if (-not $remoteAccessReady) {
|
||||
$issues.Add('RDP/WinRM or the authorized domain group is not fully configured.')
|
||||
}
|
||||
}
|
||||
|
||||
$result = [pscustomobject]@{
|
||||
ComputerName = $env:COMPUTERNAME
|
||||
Domain = $computer.Domain
|
||||
DomainJoined = [bool]$computer.PartOfDomain
|
||||
ProviderRegistered = $providerRegistered
|
||||
ProviderBinary = $registeredDll
|
||||
ProviderBinaryPresent = [bool]$providerBinaryPresent
|
||||
DefaultProviderConfigured = $defaultProviderConfigured
|
||||
PasswordProviderPreserved = $passwordProviderPreserved
|
||||
SettingsPresent = [bool]$settings
|
||||
ClientCertificatePresent = [bool]$clientCertificatePresent
|
||||
ServerCertificateTrusted = $serverCertificateTrusted
|
||||
DotNetRuntimePresent = $dotNetRuntimePresent
|
||||
BrokerHealth = $brokerHealth
|
||||
RemoteAccessReady = $remoteAccessReady
|
||||
IsValid = $issues.Count -eq 0
|
||||
Issues = $issues.ToArray()
|
||||
}
|
||||
|
||||
$result
|
||||
if ($Enforce -and -not $result.IsValid) {
|
||||
throw "SGU client enrollment is invalid: $($issues -join ' ')"
|
||||
}
|
||||
Reference in New Issue
Block a user