Entra/EntraConditionalAccessChecks.ps1
|
# ------------------------------------------------------------------- # Entra ID -- Conditional Access & Device Checks # Extracted from Get-EntraSecurityConfig.ps1 (#256) # Runs in shared scope: $settings, $checkIdCounter, Add-Setting, $context # ------------------------------------------------------------------- [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] param() # ------------------------------------------------------------------ # 11. Conditional Access Policy Count # ------------------------------------------------------------------ try { Write-Verbose "Counting conditional access policies..." $graphParams = @{ Method = 'GET' Uri = '/v1.0/identity/conditionalAccess/policies' ErrorAction = 'Stop' } $caPolicies = Invoke-MgGraphRequest @graphParams $policyList = if ($caPolicies -and $caPolicies['value']) { @($caPolicies['value']) } else { @() } $caCount = $policyList.Count $enabledCount = @($policyList | Where-Object { $_['state'] -eq 'enabled' }).Count $settingParams = @{ Category = 'Conditional Access' Setting = 'Total CA Policies' CurrentValue = "$caCount" RecommendedValue = '1+' Status = 'Info' CheckId = 'ENTRA-CA-002' Remediation = 'Informational — review Conditional Access policy coverage for your organization.' } Add-Setting @settingParams $settingParams = @{ Category = 'Conditional Access' Setting = 'Enabled CA Policies' CurrentValue = "$enabledCount" RecommendedValue = '1+' Status = $(if ($enabledCount -gt 0) { 'Pass' } else { 'Warning' }) CheckId = 'ENTRA-CA-003' Remediation = 'Run: Get-MgIdentityConditionalAccessPolicy | Where-Object {$_.State -eq ''enabled''}. Ensure policies are set to On, not Report-only.' } Add-Setting @settingParams } catch { Write-Warning "Could not check CA policies: $_" } # ------------------------------------------------------------------ # 13. Device Registration Policy (CIS 5.1.4.1, 5.1.4.2, 5.1.4.3) # ------------------------------------------------------------------ try { Write-Verbose "Checking device registration policy..." $graphParams = @{ Method = 'GET' Uri = '/v1.0/policies/deviceRegistrationPolicy' ErrorAction = 'Stop' } $devicePolicy = Invoke-MgGraphRequest @graphParams if ($devicePolicy) { # CIS 5.1.4.1 -- Device join restricted $joinType = $devicePolicy['azureADJoin']['allowedToJoin']['@odata.type'] $joinRestricted = $joinType -ne '#microsoft.graph.allDeviceRegistrationMembership' $settingParams = @{ Category = 'Device Management' Setting = 'Azure AD Join Restriction' CurrentValue = $(if ($joinRestricted) { 'Restricted' } else { 'All users allowed' }) RecommendedValue = 'Restricted to specific users/groups' Status = $(if ($joinRestricted) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-DEVICE-001' Remediation = 'Entra admin center > Devices > Device settings > Users may join devices to Microsoft Entra > Selected. Restrict to a specific group of authorized users.' } Add-Setting @settingParams # CIS 5.1.4.2 -- Max devices per user $maxDevices = $devicePolicy['userDeviceQuota'] $settingParams = @{ Category = 'Device Management' Setting = 'Maximum Devices Per User' CurrentValue = "$maxDevices" RecommendedValue = '15 or fewer' Status = $(if ($maxDevices -le 15) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-DEVICE-002' Remediation = 'Entra admin center > Devices > Device settings > Maximum number of devices per user. Set to 15 or lower.' } Add-Setting @settingParams # CIS 5.1.4.3 -- Global admins not added as local admin on join $gaLocalAdmin = $true # Default assumption if ($devicePolicy['azureADJoin']['localAdmins']) { $gaLocalAdmin = $devicePolicy['azureADJoin']['localAdmins']['enableGlobalAdmins'] } $settingParams = @{ Category = 'Device Management' Setting = 'Global Admins as Local Admin on Join' CurrentValue = $(if ($gaLocalAdmin) { 'Enabled' } else { 'Disabled' }) RecommendedValue = 'Disabled' Status = $(if (-not $gaLocalAdmin) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-DEVICE-003' Remediation = 'Entra admin center > Devices > Device settings > Global administrator is added as local administrator on the device during Azure AD Join > No.' } Add-Setting @settingParams } } catch { Write-Warning "Could not check device registration policy: $_" } # ------------------------------------------------------------------ # 19. Device Registration Extensions (CIS 5.1.4.4, 5.1.4.5, 5.1.4.6) # ------------------------------------------------------------------ try { Write-Verbose "Checking extended device registration settings..." $graphParams = @{ Method = 'GET' Uri = '/beta/policies/deviceRegistrationPolicy' ErrorAction = 'Stop' } $devicePolicyBeta = Invoke-MgGraphRequest @graphParams if ($devicePolicyBeta) { # CIS 5.1.4.4 -- Local admin assignment limited during Entra join $localAdminSettings = $devicePolicyBeta['azureADJoin']['localAdmins'] $additionalAdmins = if ($localAdminSettings -and $localAdminSettings['registeredUsers']) { $localAdminSettings['registeredUsers']['additionalLocalAdminsCount'] } else { 0 } $settingParams = @{ Category = 'Device Management' Setting = 'Local Admin Assignment on Entra Join' CurrentValue = "Additional local admins configured: $additionalAdmins" RecommendedValue = 'Minimal local admin assignment' Status = $(if ($additionalAdmins -le 0) { 'Pass' } else { 'Review' }) CheckId = 'ENTRA-DEVICE-004' Remediation = 'Entra admin center > Devices > Device settings > Manage Additional local administrators on all Azure AD joined devices. Minimize additional local admins.' } Add-Setting @settingParams # CIS 5.1.4.5 -- LAPS enabled $lapsEnabled = $false if ($devicePolicyBeta['localAdminPassword']) { $lapsEnabled = $devicePolicyBeta['localAdminPassword']['isEnabled'] } $settingParams = @{ Category = 'Device Management' Setting = 'Local Administrator Password Solution (LAPS)' CurrentValue = $(if ($lapsEnabled) { 'Enabled' } else { 'Disabled' }) RecommendedValue = 'Enabled' Status = $(if ($lapsEnabled) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-DEVICE-005' Remediation = 'Entra admin center > Devices > Device settings > Enable Microsoft Entra Local Administrator Password Solution (LAPS) > Yes.' } Add-Setting @settingParams # CIS 5.1.4.6 -- BitLocker recovery key restricted # Beta API may expose this via deviceRegistrationPolicy or directorySettings $settingParams = @{ Category = 'Device Management' Setting = 'BitLocker Recovery Key Restriction' CurrentValue = 'Review -- verify users cannot read own BitLocker keys' RecommendedValue = 'Users restricted from recovering BitLocker keys' Status = 'Review' CheckId = 'ENTRA-DEVICE-006' Remediation = 'Entra admin center > Devices > Device settings > Restrict users from recovering the BitLocker key(s) for their owned devices > Yes.' } Add-Setting @settingParams } } catch { Write-Warning "Could not check extended device registration settings: $_" } |