Gestion d'entreprise et cloud¶
Ce que vous allez apprendre¶
- Le chemin complet qu'emprunte une strategie Intune pour atteindre le registre : MDM Agent, CSP, PolicyManager
- Comment creer un profil OMA-URI personnalise et retrouver ses traces dans le registre
- Les cles de registre qui revelent le type de jonction Entra ID (Azure AD Join, Hybrid Join, Registered)
- L'anatomie des cles SCCM/ConfigMgr et les methodes de detection basees sur le registre
- Le role du registre pendant le provisionnement Autopilot et l'Enrollment Status Page
- L'utilisation de PowerShell DSC, Ansible, Chef et Puppet pour gerer le registre a grande echelle
- La resolution des conflits quand GPO, MDM et configuration locale modifient la meme valeur
- Les cles de telemetrie et de conformite alignees sur les benchmarks CIS et les STIG
- Le diagnostic complet d'un poste d'entreprise connecte au cloud
Le registre, point de convergence de l'entreprise moderne¶
Ouvrez une invite PowerShell en tant qu'administrateur et executez :
# Show all MDM policy sources currently writing to the registry
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\PolicyManager\Providers" -ErrorAction SilentlyContinue |
ForEach-Object { [PSCustomObject]@{
Provider = $_.PSChildName
Policies = (Get-ChildItem $_.PSPath -Recurse -ErrorAction SilentlyContinue).Count
}} | Format-Table -AutoSize
Provider Policies
-------- --------
{B1E4B625-1B5C-4113-B1D0-A8D7D2B5ACE7} 47
{D4073CA3-7CFE-4B55-B73D-F1EC21062289} 12
Chaque GUID represente une source de configuration -- Intune, une GPO convertie, ou un profil local. Tout converge vers le meme endroit : le registre Windows.
Analogie
Le registre dans un environnement d'entreprise cloud fonctionne comme le tableau de bord d'un aeroport. Plusieurs compagnies (Intune, GPO, SCCM) envoient des instructions de vol (des strategies). Le tableau de bord (le registre) affiche l'etat final. Quand deux compagnies revendiquent la meme porte d'embarquement, des regles de priorite tranchent.
En resume
- Le registre est le point de convergence de toutes les sources de configuration en entreprise : Intune, GPO, SCCM, outils tiers
- Chaque source est identifiable par un GUID dans PolicyManager\Providers
- Des regles de priorite determinent quelle source prevaut quand plusieurs ecrivent la meme valeur
Microsoft Intune et le registre¶
Le chemin d'une strategie : de la console au registre¶
Quand un administrateur configure une strategie dans le portail Intune, la valeur ne tombe pas directement dans le registre. Elle traverse une chaine de composants :
sequenceDiagram
participant Admin as Portail Intune
participant AAD as Entra ID
participant MDM as MDM Agent<br/>(OmaDMClient)
participant CSP as Configuration<br/>Service Provider
participant Reg as Registre Windows
Admin->>AAD: Publie la strategie
AAD->>MDM: Notification de synchronisation
MDM->>AAD: Recupere les strategies en attente
MDM->>CSP: Transmet les parametres OMA-URI
CSP->>Reg: Ecrit les valeurs de registre
CSP-->>MDM: Confirme l'application
MDM-->>AAD: Rapporte le statut de conformite Le MDM Agent (OmaDMClient.exe) est le moteur local. Il communique avec Entra ID via HTTPS, recupere les strategies et les confie aux Configuration Service Providers (CSP). Chaque CSP gere un domaine fonctionnel precis : Policy, WiFi, VPN, BitLocker, etc.
OMA-URI et Configuration Service Providers¶
Le protocole OMA-DM (Open Mobile Alliance Device Management) est la norme utilisee par Windows pour recevoir des instructions MDM. Chaque parametre est adresse par un OMA-URI -- un chemin hierarchique qui pointe vers un noeud CSP.
Exemple d'OMA-URI pour desactiver Cortana :
Decomposition :
| Segment | Signification |
|---|---|
./Device | Cible la machine (et non l'utilisateur) |
Vendor/MSFT | Espace de noms Microsoft |
Policy/Config | CSP Policy, branche de configuration |
Experience | Zone de strategie (area) |
AllowCortana | Nom du parametre |
Le CSP Policy est le plus utilise. Il traduit les OMA-URI en ecritures de registre sous des chemins previsibles.
Policy CSP : le pont vers le registre¶
Quand le CSP Policy recoit une instruction, il ecrit la valeur dans deux emplacements :
HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\<Area>\<PolicyName>
HKLM\SOFTWARE\Microsoft\PolicyManager\Providers\{GUID}\default\Device\<Area>\<PolicyName>
Le premier chemin (current) represente l'etat actif -- la valeur effectivement appliquee. Le second chemin (Providers\{GUID}) garde la trace de qui a defini cette valeur.
# Examine the active MDM policy for a specific area
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device\Experience" -ErrorAction SilentlyContinue
AllowCortana : 0
AllowTailoredExperiences : 0
AllowThirdPartySuggestionsInWindowsSpotlight : 0
PSPath : Microsoft.PowerShell.Core\Registry::...
ADMX-backed policies
Certaines strategies Intune sont basees sur des modeles ADMX. Elles sont stockees sous un emplacement specifique :
Ce chemin contient les valeurs par defaut du modele ADMX. La valeur effective reste dans current\device.
Creer un profil OMA-URI personnalise¶
Certains parametres de registre n'ont pas de CSP dedie. Intune permet alors d'utiliser un profil OMA-URI personnalise pour ecrire directement dans le registre.
Etape 1 -- Identifiez la cle et la valeur cibles :
HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer
ValueName: DisableSearchBoxSuggestions
Type: REG_DWORD
Data: 1
Etape 2 -- Construisez l'OMA-URI correspondant. Pour les strategies ADMX ingerees :
Pour une ecriture directe via le CSP Registry (si disponible) :
./Device/Vendor/MSFT/Registry/HKLM/SOFTWARE/Policies/Microsoft/Windows/Explorer/DisableSearchBoxSuggestions
Etape 3 -- Dans le portail Intune :
- Naviguez vers Devices > Configuration profiles > Create profile
- Selectionnez Windows 10 and later, puis Templates > Custom
- Ajoutez un parametre OMA-URI :
- Name : Disable Search Box Suggestions
- OMA-URI : le chemin construit a l'etape 2
- Data type : Integer
- Value : 1
Etape 4 -- Verifiez l'application sur le poste client :
# Force an Intune sync and check the registry
Start-Process "ms-device-enrollment:?mode=mdm"
Start-Sleep -Seconds 30
# Verify the policy was written
Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" -Name "DisableSearchBoxSuggestions" -ErrorAction SilentlyContinue
DisableSearchBoxSuggestions : 1
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows
PSChildName : Explorer
PSProvider : Microsoft.PowerShell.Core\Registry
PolicyManager dans le registre¶
Les trois branches du PolicyManager meritent une exploration detaillee :
| Chemin | Role | Contenu typique |
|---|---|---|
HKLM\SOFTWARE\Microsoft\PolicyManager\current\device | Etat actif des strategies appareil | Valeurs effectives appliquees |
HKLM\SOFTWARE\Microsoft\PolicyManager\current\user\{SID} | Etat actif des strategies utilisateur | Valeurs par utilisateur |
HKLM\SOFTWARE\Microsoft\PolicyManager\Providers\{GUID} | Source de chaque strategie | GUID du fournisseur (Intune, local, etc.) |
HKLM\SOFTWARE\Microsoft\PolicyManager\AdmxDefault | Valeurs par defaut ADMX | Modeles charges par Intune |
HKLM\SOFTWARE\Microsoft\PolicyManager\AdmxInstalled | Modeles ADMX installes | Liste des fichiers ADMX ingeres |
# List all PolicyManager providers and their policy count
$providers = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\PolicyManager\Providers" -ErrorAction SilentlyContinue
foreach ($provider in $providers) {
$guid = $provider.PSChildName
$count = (Get-ChildItem $provider.PSPath -Recurse -ErrorAction SilentlyContinue).Count
Write-Output "Provider: $guid -> $count policies"
}
Provider: B1E4B625-1B5C-4113-B1D0-A8D7D2B5ACE7 -> 47 policies
Provider: D4073CA3-7CFE-4B55-B73D-F1EC21062289 -> 12 policies
Provider: 7C54C8A0-D2B0-4F3E-BE6C-2F0A5E848D90 -> 5 policies
Scripts de remediation et registre¶
Les scripts de remediation (Remediations) dans Intune permettent de detecter et corriger des ecarts de configuration. Le schema classique est :
- Un script de detection lit une valeur de registre
- S'il detecte un ecart, il retourne un code de sortie non-zero
- Un script de remediation corrige la valeur
# Detection script: check if telemetry is set to minimum
$path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
$expected = 1
$current = (Get-ItemProperty -Path $path -Name "AllowTelemetry" -ErrorAction SilentlyContinue).AllowTelemetry
if ($current -eq $expected) {
Write-Output "Compliant: AllowTelemetry is $current"
exit 0
} else {
Write-Output "Non-compliant: AllowTelemetry is $current (expected $expected)"
exit 1
}
# Remediation script: set telemetry to minimum
$path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
try {
Set-ItemProperty -Path $path -Name "AllowTelemetry" -Value 1 -Type DWord -Force
Write-Output "Remediated: AllowTelemetry set to 1"
exit 0
} catch {
Write-Output "Failed to remediate: $_"
exit 1
}
Execution context
Les scripts de remediation s'executent par defaut en tant que SYSTEM. Ils ont un acces complet a HKLM mais pas a HKCU d'un utilisateur specifique. Pour modifier HKCU, configurez le script pour s'executer dans le contexte utilisateur dans le portail Intune.
En resume
- Une strategie Intune traverse la chaine MDM Agent → CSP → registre ; le CSP Policy ecrit dans PolicyManager\current et PolicyManager\Providers
- Les profils OMA-URI personnalises permettent d'ecrire des valeurs de registre non couvertes par les CSP natifs
- Les scripts de remediation detectent et corrigent les ecarts de configuration en s'executant par defaut sous le compte SYSTEM
Entra ID (Azure AD) et le registre¶
Types de jonction¶
Un poste Windows peut etre connecte a Entra ID de trois manieres :
| Type de jonction | Scenario | Gestion MDM | Acces conditionnel |
|---|---|---|---|
| Azure AD Join | Poste cloud-only, pas de domaine AD | Oui | Oui |
| Hybrid Azure AD Join | Poste joint au domaine AD et synchronise avec Entra ID | Oui | Oui |
| Azure AD Registered | Appareil personnel (BYOD) | Optionnel | Limite |
Chaque type laisse des empreintes specifiques dans le registre.
Cles de registre par type de jonction¶
Azure AD Join et Hybrid Join¶
Cette cle contient une sous-cle nommee par le TenantId (GUID du locataire Entra ID) :
# Display Entra ID join information from the registry
Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo" -ErrorAction SilentlyContinue |
ForEach-Object {
$props = Get-ItemProperty $_.PSPath
[PSCustomObject]@{
TenantId = $_.PSChildName
UserEmail = $props.UserEmail
TenantName = $props.TenantName
JoinType = $props.JoinType
ThumbPrint = $props.CertThumbprint
}
} | Format-List
TenantId : a1b2c3d4-e5f6-7890-abcd-ef1234567890
UserEmail : admin@contoso.com
TenantName : Contoso
JoinType : 6
ThumbPrint : 1A2B3C4D5E6F7A8B9C0D1E2F3A4B5C6D7E8F9A0B
Les valeurs de JoinType :
| JoinType | Signification |
|---|---|
6 | Azure AD Join |
4 | Hybrid Azure AD Join |
13 | Azure AD Registered (Workplace Join) |
Identity Store¶
Ce chemin stocke les informations d'identite mises en cache localement. On y trouve le nom de l'utilisateur, son UPN et son identifiant Entra ID.
CDJ (Cloud Domain Join)¶
Cette branche contient des metadonnees supplementaires sur la jonction, notamment le certificat de l'appareil et les endpoints de decouverte.
# Read the CDJ AAD metadata
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CDJ\AAD" -ErrorAction SilentlyContinue |
Select-Object TenantId, TenantName
TenantId TenantName
-------- ----------
a1b2c3d4-e5f6-7890-abcd-ef1234567890 Contoso
Determiner le type de jonction a partir du registre seul¶
Sans executer dsregcmd /status, il est possible de determiner l'etat de jonction en examinant le registre :
# Determine Entra ID join status from registry only
function Get-JoinStatusFromRegistry {
$result = [PSCustomObject]@{
AzureADJoined = $false
HybridJoined = $false
WorkplaceJoined = $false
TenantId = $null
DomainJoined = $false
}
# Check CloudDomainJoin
$joinInfo = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo" -ErrorAction SilentlyContinue
if ($joinInfo) {
$props = Get-ItemProperty $joinInfo[0].PSPath
$result.TenantId = $joinInfo[0].PSChildName
switch ($props.JoinType) {
6 { $result.AzureADJoined = $true }
4 { $result.HybridJoined = $true }
13 { $result.WorkplaceJoined = $true }
}
}
# Check traditional domain join
$domainKey = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -ErrorAction SilentlyContinue
if ($domainKey.Domain -and $domainKey.Domain -ne "") {
$result.DomainJoined = $true
}
return $result
}
Get-JoinStatusFromRegistry | Format-List
AzureADJoined : True
HybridJoined : False
WorkplaceJoined : False
TenantId : a1b2c3d4-e5f6-7890-abcd-ef1234567890
DomainJoined : True
Hybrid Join : quand GPO et MDM coexistent¶
Dans un environnement Hybrid Join, le poste recoit des strategies a la fois des GPO Active Directory et d'Intune. Le registre porte les traces des deux sources :
- GPO ecrit sous
HKLM\SOFTWARE\Policies\... - MDM ecrit sous
HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\...
Le parametre qui determine la priorite en cas de conflit se trouve dans :
| Valeur | Type | Donnees | Effet |
|---|---|---|---|
DisableRegistration | REG_DWORD | 0 | Permet l'inscription MDM automatique |
AutoEnrollMDM | REG_DWORD | 1 | Active l'inscription automatique a Intune |
Co-management avec SCCM
En co-gestion SCCM + Intune, des workloads specifiques sont bascules vers Intune. L'etat de chaque workload est suivi dans le registre sous les cles ConfigMgr (voir la section SCCM ci-dessous).
En resume
- Le type de jonction Entra ID (Join, Hybrid, Registered) est identifiable dans le registre via CloudDomainJoin\JoinInfo et la valeur JoinType (6, 4 ou 13)
- En Hybrid Join, les GPO ecrivent sous
HKLM\SOFTWARE\Policieset MDM sousPolicyManager\current\device - La cle MDMWinsOverGP determine quelle source de configuration a priorite en cas de conflit
SCCM / ConfigMgr et le registre¶
Les cles du client Configuration Manager¶
Le client SCCM (Configuration Manager) est un agent riche qui laisse une empreinte substantielle dans le registre.
Cle principale du client¶
| Valeur | Type | Description |
|---|---|---|
TempDir | REG_SZ | Repertoire temporaire du client |
LogDirectory | REG_SZ | Emplacement des fichiers journaux |
HttpPort | REG_DWORD | Port HTTP du Management Point |
HttpsPort | REG_DWORD | Port HTTPS du Management Point |
Strategies (Policy)¶
Les sous-cles Machine\ActualConfig et Machine\RequestedConfig contiennent l'ensemble des strategies recues. Chaque strategie est identifiee par un ID unique et contient sa date de reception, son corps et ses conditions d'evaluation.
# List SCCM policy assignments
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\CCM\Policy\Machine\ActualConfig" -ErrorAction SilentlyContinue |
Select-Object PSChildName | Format-Table -AutoSize
PSChildName
-----------
CCM_Policy_Policy5.PolicyID="{c7f7da80-aa3f-4a9e-b82c-0e13f573d2e2}",PolicySource="SMS:PS1"...
CCM_Policy_Policy5.PolicyID="{f82ba86e-5d4a-4c6e-9a3b-1e8d6f0c2a47}",PolicySource="SMS:PS1"...
CCM_Policy_Policy5.PolicyID="{b19e4d3c-8a72-41f5-ae60-3c5d9b1e7f83}",PolicySource="SMS:PS1"...
Mobile Client (SMS)¶
| Valeur | Type | Description |
|---|---|---|
ProductVersion | REG_SZ | Version du client SCCM installee |
AssignedSiteCode | REG_SZ | Code du site SCCM affecte (ex: PS1) |
GPRequestedSiteAssignmentCode | REG_SZ | Code de site assigne par GPO |
# Check SCCM client version and site code
$sms = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\SMS\Mobile Client" -ErrorAction SilentlyContinue
Write-Output "Client Version: $($sms.ProductVersion)"
Write-Output "Site Code: $($sms.AssignedSiteCode)"
Methodes de detection basees sur le registre¶
Quand SCCM deploie une application, il doit pouvoir detecter si elle est deja installee. La methode de detection par registre est la plus courante :
# SCCM detection method: check if an application's registry key exists
$detectionPath = "HKLM:\SOFTWARE\Contoso\MyApp"
$detectionValue = "Version"
$expectedVersion = "2.1.0"
$actual = (Get-ItemProperty -Path $detectionPath -Name $detectionValue -ErrorAction SilentlyContinue).$detectionValue
if ($actual -ge $expectedVersion) {
Write-Output "Application detected: version $actual"
# Return $true by writing output — SCCM interprets any stdout as "detected"
} else {
# Return nothing — SCCM interprets empty stdout as "not detected"
}
Regles de detection SCCM
SCCM interprete la sortie du script de detection de maniere stricte :
- Sortie non vide (stdout) = application detectee
- Sortie vide = application non detectee
- Le code de retour (
exit code) est ignore pour les scripts PowerShell
Parametres de conformite et registre¶
Les Compliance Settings (parametres de conformite) de SCCM permettent de verifier des valeurs de registre et de rapporter l'etat de conformite. La configuration comprend :
- Un Configuration Item (CI) qui definit la cle, la valeur et le critere attendu
- Une Configuration Baseline qui regroupe les CI
- Un deploiement qui cible une collection de machines
Le CI stocke sa definition dans le registre du client sous :
Verification de la sante du client¶
Le client SCCM possede un mecanisme d'auto-verification. Les resultats sont traces dans :
| Valeur | Type | Description |
|---|---|---|
LastEvalTime | REG_SZ | Derniere evaluation du client |
LastEvalResult | REG_SZ | Resultat : Passed, Failed, NotYetEvaluated |
LastEvalResultCode | REG_DWORD | Code numerique du resultat |
# Check SCCM client health status
$eval = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\CCM\CcmEval" -ErrorAction SilentlyContinue
Write-Output "Last evaluation: $($eval.LastEvalTime)"
Write-Output "Result: $($eval.LastEvalResult)"
En resume
- Le client SCCM stocke sa configuration principale sous
HKLM\SOFTWARE\Microsoft\CCMet les strategies sous CCM\Policy - Les methodes de detection basees sur le registre sont les plus courantes pour verifier si une application est deja installee
- Le mecanisme CcmEval surveille la sante du client et trace les resultats dans
CCM\CcmEval
Windows Autopilot et le registre¶
Le provisionnement OOBE¶
Windows Autopilot automatise le deploiement de postes neufs. Pendant la phase OOBE (Out-Of-Box Experience), le registre est le journal de bord de chaque etape.
Parametres Autopilot¶
| Valeur | Type | Description |
|---|---|---|
CloudAssignedTenantId | REG_SZ | GUID du locataire Entra ID |
CloudAssignedTenantDomain | REG_SZ | Domaine du locataire (ex: contoso.onmicrosoft.com) |
IsAutopilotDevice | REG_DWORD | 1 si l'appareil est enregistre Autopilot |
CloudAssignedOobeConfig | REG_DWORD | Configuration OOBE (masque binaire) |
CloudAssignedLanguage | REG_SZ | Langue attribuee (ex: fr-FR) |
CloudAssignedRegion | REG_SZ | Region attribuee |
# Read Autopilot provisioning settings
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Provisioning\AutopilotSettings" -ErrorAction SilentlyContinue |
Select-Object CloudAssignedTenantId, CloudAssignedTenantDomain, IsAutopilotDevice, CloudAssignedOobeConfig |
Format-List
CloudAssignedTenantId : a1b2c3d4-e5f6-7890-abcd-ef1234567890
CloudAssignedTenantDomain : contoso.onmicrosoft.com
IsAutopilotDevice : 1
CloudAssignedOobeConfig : 143
Valeurs du masque CloudAssignedOobeConfig¶
| Bit | Valeur | Effet |
|---|---|---|
| 0 | 1 | Ignorer les pages de confidentialite |
| 1 | 2 | Ignorer l'EULA |
| 2 | 4 | Ignorer le compte OEM |
| 3 | 8 | Ignorer l'ajout d'un compte local |
| 7 | 128 | Desactiver le mode Cortana pendant OOBE |
Enrollment Status Page (ESP)¶
L'ESP bloque l'acces au bureau tant que les applications et strategies ne sont pas installees. Sa progression est tracee dans :
Les sous-cles suivent la progression de chaque categorie :
EnrollmentStatusTracking\
Device\
Setup\
Apps\
Tracking\
{PackageId1} -> InstallationState = 2 (installed)
{PackageId2} -> InstallationState = 1 (in progress)
Policies\
Tracking\
{PolicyId1} -> InstallationState = 2
# Monitor ESP progress for device setup apps
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\Autopilot\EnrollmentStatusTracking\Device\Setup\Apps\Tracking" -ErrorAction SilentlyContinue |
ForEach-Object {
$props = Get-ItemProperty $_.PSPath
[PSCustomObject]@{
PackageId = $_.PSChildName
InstallationState = $props.InstallationState
LastError = $props.LastError
}
} | Format-Table -AutoSize
PackageId InstallationState LastError
--------- ----------------- ---------
{e3a1b2c4-5d6f-7890-abcd-1234567890ab} 2 0
{f4b2c3d5-6e7f-8901-bcde-2345678901bc} 2 0
{a5c3d4e6-7f80-9012-cdef-3456789012cd} 1 0
| InstallationState | Signification |
|---|---|
1 | Installation en cours |
2 | Installe avec succes |
3 | Echec de l'installation |
Diagnostics Autopilot¶
Cette cle contient les resultats detailles de chaque etape du provisionnement :
| Valeur | Type | Description |
|---|---|---|
CloudAssignedTenantUpn | REG_SZ | UPN utilise pour l'inscription |
IsDevicePersonalized | REG_DWORD | 1 si le profil utilisateur a ete configure |
JoinType | REG_DWORD | Type de jonction effectuee |
LastAutopilotProfileSyncTime | REG_SZ | Derniere synchronisation du profil |
White Glove / Pre-provisionnement¶
Le mode White Glove (renomme Pre-provisioning) permet aux techniciens de preparer un poste avant de le livrer a l'utilisateur. Le statut est suivi dans :
| Valeur | Type | Description |
|---|---|---|
PreProvisioningCompleted | REG_DWORD | 1 si le pre-provisionnement est termine |
WhiteGloveTimeout | REG_DWORD | Delai avant expiration (en minutes) |
WhiteGloveSuccess | REG_DWORD | 1 si le White Glove a reussi |
# Verify White Glove / Pre-provisioning status
$autopilot = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Provisioning\AutopilotSettings" -ErrorAction SilentlyContinue
if ($autopilot.PreProvisioningCompleted -eq 1) {
Write-Output "Pre-provisioning completed successfully"
} else {
Write-Output "Pre-provisioning NOT completed"
}
En resume
- Les parametres Autopilot sont stockes sous
AutopilotSettingsavec le TenantId, la langue et le masque de configuration OOBE - L'Enrollment Status Page (ESP) trace la progression de chaque application et strategie sous EnrollmentStatusTracking
- Le mode White Glove (pre-provisionnement) enregistre son statut de completion dans AutopilotSettings
PowerShell DSC et le registre¶
La ressource Registry dans DSC¶
PowerShell Desired State Configuration (DSC) permet de declarer l'etat souhaite du systeme. La ressource Registry gere les cles et valeurs de registre de maniere idempotente.
Parametres de la ressource Registry :
| Parametre | Requis | Description |
|---|---|---|
Key | Oui | Chemin complet de la cle (ex: HKLM:\SOFTWARE\Contoso) |
ValueName | Oui | Nom de la valeur |
Ensure | Non | Present (par defaut) ou Absent |
ValueType | Non | String, Binary, Dword, Qword, MultiString, ExpandString |
ValueData | Non | Donnees de la valeur |
Force | Non | $true pour creer les cles parentes manquantes |
Configuration DSC complete¶
# DSC Configuration: enforce corporate registry settings
Configuration EnterpriseRegistryBaseline {
Import-DscResource -ModuleName PSDesiredStateConfiguration
Node "localhost" {
# Disable Windows telemetry beyond required level
Registry DisableTelemetry {
Key = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"
ValueName = "AllowTelemetry"
ValueType = "Dword"
ValueData = "1"
Ensure = "Present"
Force = $true
}
# Enforce NTP server configuration
Registry NtpServer {
Key = "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Parameters"
ValueName = "NtpServer"
ValueType = "String"
ValueData = "time.windows.com,0x9"
Ensure = "Present"
}
# Disable autorun on all drives
Registry DisableAutorun {
Key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
ValueName = "NoDriveTypeAutoRun"
ValueType = "Dword"
ValueData = "255"
Ensure = "Present"
Force = $true
}
# Block anonymous enumeration of SAM accounts
Registry RestrictAnonymousSAM {
Key = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
ValueName = "RestrictAnonymousSAM"
ValueType = "Dword"
ValueData = "1"
Ensure = "Present"
}
# Remove a deprecated registry value
Registry RemoveDeprecatedKey {
Key = "HKLM:\SOFTWARE\Contoso\LegacyApp"
ValueName = "EnableV1Protocol"
Ensure = "Absent"
}
}
}
# Compile the configuration to a MOF file
EnterpriseRegistryBaseline -OutputPath "C:\DSC\EnterpriseBaseline"
# Apply the configuration
Start-DscConfiguration -Path "C:\DSC\EnterpriseBaseline" -Wait -Verbose -Force
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ...
VERBOSE: An LCM method call arrived from computer LOCALHOST with user sid ...
VERBOSE: [LOCALHOST]: LCM: [Start Set ]
VERBOSE: [LOCALHOST]: LCM: [Start Resource] [[Registry]DisableTelemetry]
VERBOSE: [LOCALHOST]: [[Registry]DisableTelemetry] (SET) Set registry key value ...
VERBOSE: [LOCALHOST]: LCM: [End Set ]
Operation completed successfully.
Azure Machine Configuration¶
Azure Machine Configuration (anciennement Azure Policy Guest Configuration) est le successeur cloud de DSC. Il utilise le meme format de configuration mais l'execute via un agent Azure.
Le fonctionnement :
- Une Azure Policy de type
AuditIfNotExistsouDeployIfNotExistscible des machines - L'agent Guest Configuration telecharge le package de configuration
- Le package contient une configuration DSC compilee (MOF)
- L'agent evalue la configuration et rapporte l'etat de conformite
# Check Guest Configuration agent status
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\GuestConfig" -ErrorAction SilentlyContinue |
ForEach-Object { Get-ItemProperty $_.PSPath } | Format-List
ComplianceStatus : Compliant
LastComplianceStatusChecked : 2026-04-03T10:30:00Z
ConfigurationMode : Audit
ConfigurationName : AzureWindowsBaseline
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\GuestConfig\Configuration\AzureWindowsBaseline
Le registre local du poste contient les resultats d'evaluation sous :
| Valeur | Type | Description |
|---|---|---|
ComplianceStatus | REG_SZ | Compliant ou NonCompliant |
LastComplianceStatusChecked | REG_SZ | Horodatage de la derniere verification |
ConfigurationMode | REG_SZ | Audit ou ApplyAndMonitor |
Azure Policy et registre
Avec le mode DeployIfNotExists, Azure Policy peut corriger automatiquement les valeurs de registre non conformes. C'est l'equivalent cloud des scripts de remediation Intune, mais avec une gouvernance centralisee via Azure Policy.
En resume
- La ressource DSC Registry gere les cles et valeurs de maniere idempotente avec le parametre Force pour creer les cles parentes manquantes
- Azure Machine Configuration (anciennement Guest Configuration) est le successeur cloud de DSC, pilote par Azure Policy
- Les resultats de conformite sont stockes localement sous
HKLM\SOFTWARE\Microsoft\GuestConfig\Configuration
Ansible, Chef, Puppet et le registre¶
Ansible : module win_regedit¶
Ansible gere les machines Windows via WinRM. Le module win_regedit permet de manipuler le registre.
# Ansible playbook: enforce registry settings on Windows hosts
---
- name: Apply enterprise registry baseline
hosts: windows_servers
tasks:
- name: Disable SMBv1 server
ansible.windows.win_regedit:
path: HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
name: SMB1
data: 0
type: dword
state: present
- name: Set minimum TLS version to 1.2
ansible.windows.win_regedit:
path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client
name: Enabled
data: 1
type: dword
state: present
- name: Disable TLS 1.0
ansible.windows.win_regedit:
path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client
name: Enabled
data: 0
type: dword
state: present
- name: Remove legacy application key
ansible.windows.win_regedit:
path: HKLM:\SOFTWARE\LegacyVendor\OldApp
state: absent
delete_key: true
Chef : ressource registry_key¶
Chef utilise la ressource registry_key pour gerer le registre Windows.
# Chef recipe: enforce registry settings
# Disable autorun on all drives
registry_key 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer' do
values [{
name: 'NoDriveTypeAutoRun',
type: :dword,
data: 255
}]
action :create
end
# Enforce Windows Update settings
registry_key 'HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' do
values [
{ name: 'NoAutoUpdate', type: :dword, data: 0 },
{ name: 'AUOptions', type: :dword, data: 4 },
{ name: 'ScheduledInstallDay', type: :dword, data: 0 },
{ name: 'ScheduledInstallTime', type: :dword, data: 3 }
]
action :create
recursive true
end
# Remove an obsolete registry key and all subkeys
registry_key 'HKLM\SOFTWARE\ObsoleteVendor' do
action :delete_key
recursive true
end
Puppet : type registry¶
Puppet gere le registre Windows via le module puppetlabs/registry.
# Puppet manifest: enforce registry settings
# Ensure the parent key exists
registry_key { 'HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection':
ensure => present,
}
# Set telemetry to minimum
registry_value { 'HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection\AllowTelemetry':
ensure => present,
type => dword,
data => 1,
}
# Disable Remote Desktop NLA requirement (if needed)
registry_value { 'HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\UserAuthentication':
ensure => present,
type => dword,
data => 1,
}
# Remove a deprecated value
registry_value { 'HKLM\SOFTWARE\LegacyVendor\OldApp\EnableFeatureX':
ensure => absent,
}
Comparaison des trois outils¶
| Capacite | Ansible | Chef | Puppet |
|---|---|---|---|
| Creation de cle | state: present | action :create | ensure => present |
| Suppression de cle | state: absent | action :delete_key | ensure => absent |
| Creation recursive | Automatique | recursive true | Automatique |
| Types supportes | string, dword, qword, binary, multistring, expandstring | :string, :dword, :qword, :binary, :multi_string, :expand_string | string, dword, qword, binary, array, expand |
| Acces HKCU | Via ansible.windows.win_regedit avec hive | Via registry_key directement | Via registry_value directement |
| Architecture (32/64) | Parametre architecture | Parametre architecture | Non natif (workaround) |
| Mode check/dry-run | --check | --why-run | --noop |
| Protocole | WinRM / SSH | Chef Client (HTTPS) | Puppet Agent (HTTPS) |
Quel outil choisir ?
- Ansible : ideal pour les operations ponctuelles et les environnements heterogenes (Linux + Windows). Sans agent.
- Chef : adapte aux organisations qui favorisent une approche "infrastructure as code" avec des cookbooks versionnes.
- Puppet : puissant pour la gestion de conformite continue avec des rapports detailles.
En resume
- Ansible (win_regedit), Chef (registry_key) et Puppet (registry_value) gerent tous le registre avec creation, suppression et mode dry-run
- Ansible est sans agent (via WinRM), tandis que Chef et Puppet necessitent un agent local
- Les trois outils supportent tous les types de donnees du registre et la creation recursive de cles
Conflits entre sources de configuration¶
L'ordre de priorite¶
Quand plusieurs sources tentent de definir la meme valeur de registre, Windows applique un ordre de priorite strict :
graph TD
A["Local Registry Edit<br/>(regedit, script)<br/>Priorite : BASSE"] --> B["Group Policy (GPO)<br/>HKLM\SOFTWARE\Policies\...<br/>Priorite : MOYENNE"]
B --> C{"MDMWinsOverGP<br/>active ?"}
C -->|Non| D["GPO gagne<br/>MDM ignore"]
C -->|Oui| E["MDM (Intune) gagne<br/>GPO ignore"]
style A fill:#e8f5e9
style B fill:#fff3e0
style C fill:#e3f2fd
style D fill:#ffcdd2
style E fill:#c8e6c9 Par defaut, les GPO priment sur MDM. Pour inverser ce comportement :
| Valeur | Type | Donnees | Effet |
|---|---|---|---|
ControlPolicyConflict | REG_DWORD | -- | Sous-cle contenant la strategie de conflit |
| Valeur | Type | Donnees | Effet |
|---|---|---|---|
MDMWinsOverGP | REG_DWORD | 1 | MDM (Intune) a priorite sur les GPO |
MDMWinsOverGP | REG_DWORD | 0 | GPO garde la priorite (par defaut) |
# Check if MDM has priority over GPO
$mdmConflict = Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\MDM\ControlPolicyConflict" -ErrorAction SilentlyContinue
if ($mdmConflict.MDMWinsOverGP -eq 1) {
Write-Output "MDM (Intune) wins over Group Policy"
} else {
Write-Output "Group Policy wins over MDM (default behavior)"
}
Impact de MDMWinsOverGP
Activer MDMWinsOverGP desactive toutes les GPO pour les zones couvertes par MDM. Ce n'est pas un parametrage granulaire. Avant de l'activer, assurez-vous que toutes les strategies critiques sont migrees vers Intune.
Diagnostic : quelle source a defini une valeur ?¶
Pour determiner quelle source a ecrit une valeur specifique :
# Identify the source of a specific policy setting
function Get-PolicySource {
param(
[string]$Area = "Experience",
[string]$PolicyName = "AllowCortana"
)
$sources = @()
# Check MDM PolicyManager
$mdm = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device\$Area" -Name $PolicyName -ErrorAction SilentlyContinue
if ($mdm) {
$sources += [PSCustomObject]@{
Source = "MDM (PolicyManager)"
Value = $mdm.$PolicyName
Path = "HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device\$Area"
}
}
# Check GPO Policies
$gpoPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\$Area"
$gpo = Get-ItemProperty $gpoPath -Name $PolicyName -ErrorAction SilentlyContinue
if ($gpo) {
$sources += [PSCustomObject]@{
Source = "Group Policy"
Value = $gpo.$PolicyName
Path = $gpoPath
}
}
# Check local preferences
$localPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\$Area"
$local = Get-ItemProperty $localPath -Name $PolicyName -ErrorAction SilentlyContinue
if ($local) {
$sources += [PSCustomObject]@{
Source = "Local Setting"
Value = $local.$PolicyName
Path = $localPath
}
}
return $sources
}
Get-PolicySource -Area "Experience" -PolicyName "AllowCortana" | Format-Table -AutoSize
Source Value Path
------ ----- ----
MDM (PolicyManager) 0 HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device\Experience
Group Policy 0 HKLM:\SOFTWARE\Policies\Microsoft\Windows\Experience
Organigramme de resolution des conflits¶
flowchart TD
START["Valeur de registre<br/>en conflit"] --> Q1{"MDMWinsOverGP<br/>= 1 ?"}
Q1 -->|Oui| Q2{"Strategie MDM<br/>definie ?"}
Q2 -->|Oui| MDM["Valeur MDM<br/>appliquee"]
Q2 -->|Non| Q3{"GPO definie ?"}
Q3 -->|Oui| GPO["Valeur GPO<br/>appliquee"]
Q3 -->|Non| LOCAL["Valeur locale<br/>appliquee"]
Q1 -->|Non| Q4{"GPO definie ?"}
Q4 -->|Oui| GPO2["Valeur GPO<br/>appliquee"]
Q4 -->|Non| Q5{"Strategie MDM<br/>definie ?"}
Q5 -->|Oui| MDM2["Valeur MDM<br/>appliquee"]
Q5 -->|Non| LOCAL2["Valeur locale<br/>appliquee"]
style MDM fill:#c8e6c9
style MDM2 fill:#c8e6c9
style GPO fill:#fff3e0
style GPO2 fill:#fff3e0
style LOCAL fill:#e8f5e9
style LOCAL2 fill:#e8f5e9 Cas special : co-gestion SCCM + Intune
En co-gestion, le basculement des workloads ajoute un niveau de complexite. Meme si MDMWinsOverGP est actif, un workload reste sous SCCM tant qu'il n'a pas ete explicitement bascule vers Intune dans la console ConfigMgr.
En resume
- Par defaut, les GPO ont priorite sur MDM ; la cle MDMWinsOverGP inverse ce comportement de maniere globale (pas granulaire)
- La fonction Get-PolicySource permet d'identifier quelle source (MDM, GPO, local) a defini une valeur specifique
- En co-gestion SCCM + Intune, un workload reste sous SCCM tant qu'il n'est pas explicitement bascule
Telemetrie et conformite¶
Cles de telemetrie Windows¶
Windows collecte des donnees de diagnostic (telemetrie) dont le niveau est controlable par le registre.
AllowTelemetry¶
| Valeur | Type | Donnees | Niveau |
|---|---|---|---|
AllowTelemetry | REG_DWORD | 0 | Security (entreprise uniquement, editions Enterprise/Education) |
AllowTelemetry | REG_DWORD | 1 | Required (anciennement Basic) |
AllowTelemetry | REG_DWORD | 2 | Enhanced (supprime dans Windows 11) |
AllowTelemetry | REG_DWORD | 3 | Optional (anciennement Full) |
# Check current telemetry level
$telemetry = Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "AllowTelemetry" -ErrorAction SilentlyContinue
$levels = @{ 0 = "Security"; 1 = "Required"; 2 = "Enhanced"; 3 = "Optional" }
$level = $levels[$telemetry.AllowTelemetry]
Write-Output "Telemetry level: $($telemetry.AllowTelemetry) ($level)"
DiagTrack Service¶
| Valeur | Type | Description |
|---|---|---|
DiagTrackAuthorization | REG_DWORD | Niveau d'autorisation du service DiagTrack |
LastPersistedEventTimeOrFirstBoot | REG_QWORD | Horodatage du dernier evenement persiste |
UploadPermissionReceived | REG_DWORD | 1 si l'autorisation d'upload est recue |
CIS Benchmarks et le registre¶
Le Center for Internet Security (CIS) publie des benchmarks de securite. Voici les recommandations CIS les plus importantes et leurs chemins de registre :
| Ref. CIS | Recommandation | Chemin | Valeur | Donnees |
|---|---|---|---|---|
| 1.1.1 | Longueur minimum du mot de passe | HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters | MinimumPasswordLength | 14 |
| 2.3.1.1 | Desactiver le compte Administrateur | HKLM\SAM\SAM\Domains\Account\Users\000001F4 | F (flags) | Bit 1 set |
| 2.3.7.1 | Mode approbation administrateur | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System | EnableLUA | 1 |
| 2.3.7.3 | Comportement elevation admin | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System | ConsentPromptBehaviorAdmin | 2 |
| 2.3.7.4 | Comportement elevation standard | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System | ConsentPromptBehaviorUser | 0 |
| 2.3.10.5 | Niveau d'authentification LAN Manager | HKLM\SYSTEM\CurrentControlSet\Control\Lsa | LmCompatibilityLevel | 5 |
| 2.3.11.7 | Chiffrement systeme FIPS | HKLM\SYSTEM\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy | Enabled | 0 |
| 9.1.1 | Profil pare-feu domaine actif | HKLM\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile | EnableFirewall | 1 |
| 9.2.1 | Profil pare-feu prive actif | HKLM\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile | EnableFirewall | 1 |
| 9.3.1 | Profil pare-feu public actif | HKLM\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile | EnableFirewall | 1 |
| 18.4.1 | Desactiver l'enumeration anonyme | HKLM\SYSTEM\CurrentControlSet\Control\Lsa | RestrictAnonymous | 1 |
| 18.5.1 | Desactiver NetBIOS sur TCP/IP | HKLM\SYSTEM\CurrentControlSet\Services\NetBT\Parameters | NodeType | 2 |
| 18.9.4.1 | Desactiver Autorun | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer | NoDriveTypeAutoRun | 255 |
| 18.9.11.1 | Desactiver WDigest | HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest | UseLogonCredential | 0 |
| 18.9.25.1 | Desactiver SMBv1 | HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters | SMB1 | 0 |
| 18.9.65.1 | Telemetrie au minimum | HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection | AllowTelemetry | 1 |
# Audit CIS critical settings
$cisChecks = @(
@{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"; Name = "EnableLUA"; Expected = 1; CIS = "2.3.7.1" },
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"; Name = "LmCompatibilityLevel"; Expected = 5; CIS = "2.3.10.5" },
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile"; Name = "EnableFirewall"; Expected = 1; CIS = "9.1.1" },
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest"; Name = "UseLogonCredential"; Expected = 0; CIS = "18.9.11.1" },
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"; Name = "SMB1"; Expected = 0; CIS = "18.9.25.1" },
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection"; Name = "AllowTelemetry"; Expected = 1; CIS = "18.9.65.1" }
)
foreach ($check in $cisChecks) {
$actual = (Get-ItemProperty -Path $check.Path -Name $check.Name -ErrorAction SilentlyContinue).($check.Name)
$status = if ($actual -eq $check.Expected) { "PASS" } else { "FAIL" }
Write-Output "[$status] CIS $($check.CIS): $($check.Name) = $actual (expected $($check.Expected))"
}
[PASS] CIS 2.3.7.1: EnableLUA = 1 (expected 1)
[FAIL] CIS 2.3.10.5: LmCompatibilityLevel = (expected 5)
[PASS] CIS 9.1.1: EnableFirewall = 1 (expected 1)
[PASS] CIS 18.9.11.1: UseLogonCredential = 0 (expected 0)
[FAIL] CIS 18.9.25.1: SMB1 = (expected 0)
[PASS] CIS 18.9.65.1: AllowTelemetry = 1 (expected 1)
STIG et le registre¶
Les STIG (Security Technical Implementation Guides) de la DISA (Defense Information Systems Agency) sont des exigences de securite pour les systemes du Departement de la Defense americain. Beaucoup de recommandations STIG se traduisent en valeurs de registre.
| STIG ID | Titre | Chemin | Valeur | Donnees |
|---|---|---|---|---|
| V-220697 | Caching credentials domain logon | HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon | CachedLogonsCount | 4 |
| V-220702 | Screen saver timeout | HKCU\SOFTWARE\Policies\Microsoft\Windows\Control Panel\Desktop | ScreenSaveTimeOut | 900 |
| V-220712 | Disable Windows Installer always elevated | HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer | AlwaysInstallElevated | 0 |
| V-220726 | Prevent storage of LAN Manager hash | HKLM\SYSTEM\CurrentControlSet\Control\Lsa | NoLMHash | 1 |
| V-220928 | Disable PowerShell script block logging | HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging | EnableScriptBlockLogging | 1 |
STIG vs CIS
Les STIG sont generalement plus restrictifs que les benchmarks CIS. Les CIS proposent deux niveaux (Level 1 et Level 2), tandis que les STIG visent un niveau de securite eleve par defaut. En France, l'ANSSI publie des recommandations equivalentes dans ses guides de durcissement.
Microsoft Security Baselines¶
Microsoft publie des Security Baselines sous forme de fichiers GPO exportes. Ces baselines contiennent des centaines de parametres de registre predefinis.
# Download and examine a Security Baseline (example path after extraction)
$baselinePath = "C:\SecurityBaseline\Windows11-23H2\GPOs"
# List all registry.pol files in the baseline
Get-ChildItem $baselinePath -Recurse -Filter "registry.pol" |
ForEach-Object {
Write-Output "Baseline GPO: $($_.Directory.Parent.Name)"
Write-Output " Path: $($_.FullName)"
}
Baseline GPO: {6AC1786C-016F-11D2-945F-00C04fB984F9}
Path: C:\SecurityBaseline\Windows11-23H2\GPOs\{6AC1786C-016F-11D2-945F-00C04fB984F9}\DomainSysvol\GPO\Machine\registry.pol
Baseline GPO: {F312195B-A4D0-4C5A-9B6A-4E5C8F2D1E3A}
Path: C:\SecurityBaseline\Windows11-23H2\GPOs\{F312195B-A4D0-4C5A-9B6A-4E5C8F2D1E3A}\DomainSysvol\GPO\Machine\registry.pol
Les baselines couvrent les categories principales :
| Categorie | Exemples de parametres de registre |
|---|---|
| Credential Guard | HKLM\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard |
| Windows Defender | HKLM\SOFTWARE\Policies\Microsoft\Windows Defender |
| Audit Policy | HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Security |
| Network Security | HKLM\SYSTEM\CurrentControlSet\Services\LDAP |
| User Rights | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System |
Outil LGPO
L'outil LGPO.exe (distribue avec le Security Compliance Toolkit) permet d'appliquer des baselines sur des machines non jointes a un domaine. Il lit les fichiers registry.pol et les traduit en ecritures de registre directes.
En resume
- AllowTelemetry controle le niveau de donnees diagnostiques (0 = Security pour Enterprise, 1 = Required, 3 = Optional)
- Les benchmarks CIS et les STIG fournissent des centaines de valeurs de registre verifiables pour la conformite securite
- Les Microsoft Security Baselines sont des fichiers GPO exportes applicables via LGPO.exe sur des machines hors domaine
Depannage de l'entreprise connectee¶
Intune : strategie non appliquee¶
Quand une strategie Intune ne s'applique pas, le registre fournit les indices necessaires au diagnostic.
Etape 1 : verifier l'inscription MDM
# Check MDM enrollment status
$enrollments = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Enrollments" -ErrorAction SilentlyContinue
foreach ($enrollment in $enrollments) {
$props = Get-ItemProperty $enrollment.PSPath
if ($props.ProviderID) {
[PSCustomObject]@{
EnrollmentId = $enrollment.PSChildName
ProviderID = $props.ProviderID
UPN = $props.UPN
EnrollmentState = $props.EnrollmentState
}
}
} | Format-Table -AutoSize
EnrollmentId ProviderID UPN EnrollmentState
------------ ---------- --- ---------------
B1E4B625-1B5C-4113-B1D0-A8D7D2B5ACE7 MS DM Server admin@contoso.com 1
| EnrollmentState | Signification |
|---|---|
1 | Inscrit et actif |
2 | En cours de desinscription |
3 | Non inscrit |
Etape 2 : verifier la synchronisation
# Check last MDM sync time
$enrollmentId = (Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Enrollments" -ErrorAction SilentlyContinue |
Where-Object { (Get-ItemProperty $_.PSPath).ProviderID -eq "MS DM Server" }).PSChildName
if ($enrollmentId) {
$dmClient = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Enrollments\$enrollmentId\DMClient\MS DM Server" -ErrorAction SilentlyContinue
Write-Output "Last sync attempt: $($dmClient.LastSuccessfulSyncTime)"
Write-Output "Number of applied policies: $($dmClient.NumberOfAppliedPolicies)"
}
Etape 3 : verifier les strategies dans PolicyManager
# List all active MDM policies and their areas
$areas = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device" -ErrorAction SilentlyContinue
Write-Output "Active policy areas: $($areas.Count)"
$areas | Select-Object PSChildName | Sort-Object PSChildName | Format-Table -AutoSize
Active policy areas: 47
PSChildName
-----------
AboveLock
Accounts
ApplicationManagement
BitLocker
Browser
Connectivity
CredentialProviders
DataProtection
Defender
DeviceLock
Experience
Privacy
RemoteDesktopServices
Search
Security
Settings
Start
System
Update
WiFi
Etape 4 : forcer une synchronisation
# Trigger an Intune sync from PowerShell
$syncCmd = New-CimInstance -Namespace "root\cimv2\mdm\dmmap" `
-ClassName "MDM_DeviceAction_Provider01" `
-Property @{ ParentID = "./Vendor/MSFT/RemoteWipe"; InstanceID = "doWipe"; ActionVerb = "SyncML" } `
-ErrorAction SilentlyContinue
# Alternative: use the scheduled task
Get-ScheduledTask | Where-Object { $_.TaskName -like "*EnterpriseMgmt*" } |
Start-ScheduledTask
Problemes d'inscription MDM¶
Chaque sous-cle est un GUID representant une tentative d'inscription. Les valeurs importantes :
| Valeur | Type | Description |
|---|---|---|
ProviderID | REG_SZ | Identifiant du fournisseur MDM (MS DM Server pour Intune) |
UPN | REG_SZ | UPN de l'utilisateur inscrit |
EnrollmentState | REG_DWORD | Etat de l'inscription (voir tableau precedent) |
LastError | REG_DWORD | Code d'erreur de la derniere operation |
AADResourceID | REG_SZ | Identifiant de la ressource Entra ID |
# Detailed enrollment diagnostic
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Enrollments" -ErrorAction SilentlyContinue |
ForEach-Object {
$props = Get-ItemProperty $_.PSPath
if ($props.ProviderID) {
[PSCustomObject]@{
GUID = $_.PSChildName
Provider = $props.ProviderID
UPN = $props.UPN
State = $props.EnrollmentState
LastError = "0x{0:X8}" -f [int]$props.LastError
ResourceID = $props.AADResourceID
}
}
} | Format-List
GUID : B1E4B625-1B5C-4113-B1D0-A8D7D2B5ACE7
Provider : MS DM Server
UPN : admin@contoso.com
State : 1
LastError : 0x00000000
ResourceID : https://enrollment.manage.microsoft.com/
Hybrid Join : echec de jonction¶
Le diagnostic des problemes de Hybrid Join repose sur la comparaison entre dsregcmd /status et les cles de registre correspondantes.
# Compare dsregcmd output with registry values
Write-Output "=== dsregcmd /status ==="
$dsreg = dsregcmd /status
$dsreg | Select-String "AzureAdJoined|DomainJoined|WorkplaceJoined|TenantName|DeviceId"
Write-Output "`n=== Registry check ==="
# Cloud Domain Join info
$joinInfo = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo" -ErrorAction SilentlyContinue
if ($joinInfo) {
$props = Get-ItemProperty $joinInfo[0].PSPath
Write-Output "Registry TenantId: $($joinInfo[0].PSChildName)"
Write-Output "Registry UserEmail: $($props.UserEmail)"
Write-Output "Registry JoinType: $($props.JoinType)"
} else {
Write-Output "No CloudDomainJoin\JoinInfo found — device may not be joined"
}
# Check Automatic Device Join task
$task = Get-ScheduledTask -TaskName "Automatic-Device-Join" -TaskPath "\Microsoft\Windows\Workplace Join\" -ErrorAction SilentlyContinue
if ($task) {
Write-Output "`nAutomatic-Device-Join task state: $($task.State)"
$lastRun = (Get-ScheduledTaskInfo -TaskName "Automatic-Device-Join" -TaskPath "\Microsoft\Windows\Workplace Join\" -ErrorAction SilentlyContinue).LastRunTime
Write-Output "Last run: $lastRun"
}
=== dsregcmd /status ===
AzureAdJoined : YES
DomainJoined : YES
WorkplaceJoined : NO
TenantName : Contoso
DeviceId : d4e5f6a7-b8c9-0123-4567-890abcdef012
=== Registry check ===
Registry TenantId: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Registry UserEmail: admin@contoso.com
Registry JoinType: 4
Automatic-Device-Join task state: Ready
Last run: 4/3/2026 8:00:00 AM
Tableau de diagnostic complet¶
| Symptome | Cle de registre a verifier | Valeur attendue | Action corrective |
|---|---|---|---|
| Intune ne se synchronise pas | HKLM\SOFTWARE\Microsoft\Enrollments\{GUID}\DMClient\MS DM Server → LastSuccessfulSyncTime | Date recente (< 8h) | Forcer une synchronisation via la tache planifiee |
| Strategie MDM absente | HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\{Area} | Valeur attendue presente | Verifier l'attribution du profil dans le portail Intune |
| GPO ecrase la strategie MDM | HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\MDM\ControlPolicyConflict → MDMWinsOverGP | 1 | Activer MDMWinsOverGP si MDM doit primer |
| Hybrid Join echoue | HKLM\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo | Sous-cle avec TenantId | Verifier la tache Automatic-Device-Join, le SCP AD et la connectivite reseau |
| Autopilot bloque sur l'ESP | HKLM\SOFTWARE\Microsoft\Windows\Autopilot\EnrollmentStatusTracking\Device\Setup\Apps\Tracking\{ID} → InstallationState | 2 (installe) | Identifier l'application bloquee et verifier son deploiement |
| SCCM client absent | HKLM\SOFTWARE\Microsoft\SMS\Mobile Client → ProductVersion | Version du client (ex: 5.00.9096.1000) | Reinstaller le client SCCM |
| Telemetrie non conforme | HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection → AllowTelemetry | 0 ou 1 selon la strategie | Verifier la GPO ou le profil Intune de telemetrie |
| Enregistrement MDM desactive | HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\MDM → DisableRegistration | 0 | Verifier la GPO qui pourrait bloquer l'inscription |
# Comprehensive enterprise diagnostic script
function Invoke-EnterpriseRegistryDiagnostic {
$results = @()
# 1. Check Entra ID join status
$joinInfo = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo" -ErrorAction SilentlyContinue
$results += [PSCustomObject]@{
Check = "Entra ID Join"
Status = if ($joinInfo) { "JOINED" } else { "NOT JOINED" }
Details = if ($joinInfo) { "TenantId: $($joinInfo[0].PSChildName)" } else { "No JoinInfo found" }
}
# 2. Check MDM enrollment
$enrollment = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Enrollments" -ErrorAction SilentlyContinue |
Where-Object { (Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue).ProviderID -eq "MS DM Server" }
$results += [PSCustomObject]@{
Check = "MDM Enrollment"
Status = if ($enrollment) { "ENROLLED" } else { "NOT ENROLLED" }
Details = if ($enrollment) { "UPN: $((Get-ItemProperty $enrollment.PSPath).UPN)" } else { "No MDM enrollment found" }
}
# 3. Check PolicyManager policies
$policyAreas = (Get-ChildItem "HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device" -ErrorAction SilentlyContinue).Count
$results += [PSCustomObject]@{
Check = "MDM Policies"
Status = if ($policyAreas -gt 0) { "ACTIVE ($policyAreas areas)" } else { "NONE" }
Details = "PolicyManager areas found: $policyAreas"
}
# 4. Check SCCM client
$sccm = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\SMS\Mobile Client" -ErrorAction SilentlyContinue
$results += [PSCustomObject]@{
Check = "SCCM Client"
Status = if ($sccm.ProductVersion) { "INSTALLED ($($sccm.ProductVersion))" } else { "NOT INSTALLED" }
Details = if ($sccm.AssignedSiteCode) { "Site: $($sccm.AssignedSiteCode)" } else { "No site assigned" }
}
# 5. Check MDMWinsOverGP
$mdmWins = (Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\MDM\ControlPolicyConflict" -ErrorAction SilentlyContinue).MDMWinsOverGP
$results += [PSCustomObject]@{
Check = "MDM vs GPO Priority"
Status = if ($mdmWins -eq 1) { "MDM WINS" } else { "GPO WINS" }
Details = "MDMWinsOverGP = $mdmWins"
}
# 6. Check telemetry level
$telemetry = (Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "AllowTelemetry" -ErrorAction SilentlyContinue).AllowTelemetry
$results += [PSCustomObject]@{
Check = "Telemetry Level"
Status = switch ($telemetry) { 0 { "SECURITY" } 1 { "REQUIRED" } 2 { "ENHANCED" } 3 { "OPTIONAL" } default { "NOT SET" } }
Details = "AllowTelemetry = $telemetry"
}
$results | Format-Table -AutoSize
}
Invoke-EnterpriseRegistryDiagnostic
Check Status Details
----- ------ -------
Entra ID Join JOINED TenantId: a1b2c3d4-e5f6-...
MDM Enrollment ENROLLED UPN: admin@contoso.com
MDM Policies ACTIVE (47 areas) PolicyManager areas found: 47
SCCM Client INSTALLED (5.00.9096...) Site: PS1
MDM vs GPO Priority GPO WINS MDMWinsOverGP =
Telemetry Level REQUIRED AllowTelemetry = 1
En resume
- Le diagnostic commence par verifier l'inscription MDM (Enrollments), puis la synchronisation (DMClient) et enfin les strategies (PolicyManager)
- Pour Hybrid Join, comparez dsregcmd /status avec les cles CloudDomainJoin\JoinInfo et la tache Automatic-Device-Join
- Le script Invoke-EnterpriseRegistryDiagnostic rassemble toutes les verifications cles en un seul rapport
En resume
Le registre est le point de convergence de toutes les sources de configuration dans une entreprise moderne. Que les strategies proviennent d'Intune (via le CSP Policy et PolicyManager), de GPO (via registry.pol et la CSE Registry), de SCCM (via les parametres de conformite) ou d'outils tiers (Ansible, Chef, Puppet), elles aboutissent toutes dans les memes ruches.
Comprendre qui ecrit quoi dans le registre est essentiel pour diagnostiquer les conflits. La cle MDMWinsOverGP est le levier central de la coexistence GPO/MDM. Les cles de PolicyManager\Providers identifient la source de chaque strategie. Les benchmarks CIS et les STIG fournissent un cadre de conformite verifiable par le registre.
Dans un environnement Hybrid Join, le registre porte simultanement les traces d'Active Directory, d'Entra ID et d'Intune. Maitriser la lecture de ces cles -- CloudDomainJoin\JoinInfo, Enrollments, PolicyManager -- permet de diagnostiquer rapidement les problemes de jonction, d'inscription MDM et d'application des strategies.