Entra/EntraAdminRoleChecks.ps1
|
# ------------------------------------------------------------------- # Entra ID -- Admin Accounts & PIM Checks # Extracted from Get-EntraSecurityConfig.ps1 (#256) # Runs in shared scope: $settings, $checkIdCounter, Add-Setting, # $context, $authPolicy, Get-BreakGlassAccounts # ------------------------------------------------------------------- [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] param() # ------------------------------------------------------------------ # 2. Global Admin Count (should be 2-4, excluding break-glass) # ------------------------------------------------------------------ try { Write-Verbose "Checking global admin count..." $graphParams = @{ Method = 'GET' Uri = "/v1.0/directoryRoles?`$filter=displayName eq 'Global Administrator'" ErrorAction = 'Stop' } $globalAdminRole = Invoke-MgGraphRequest @graphParams if (-not $globalAdminRole['value'] -or $globalAdminRole['value'].Count -eq 0) { $settingParams = @{ Category = 'Admin Accounts' Setting = 'Global Administrator Count' CurrentValue = 'Role not activated' RecommendedValue = '2-4' Status = 'Warning' CheckId = 'ENTRA-ADMIN-001' Remediation = 'The Global Administrator directory role is not activated in this tenant. Activate the role by assigning at least one user, then re-run the assessment.' } Add-Setting @settingParams } else { $roleId = $globalAdminRole['value'][0]['id'] $graphParams = @{ Method = 'GET' Uri = "/v1.0/directoryRoles/$roleId/members" ErrorAction = 'Stop' } $members = Invoke-MgGraphRequest @graphParams $allAdmins = if ($members -and $members['value']) { @($members['value']) } else { @() } # Exclude break-glass accounts from the operational admin count $breakGlassAdmins = Get-BreakGlassAccounts -Users $allAdmins $operationalAdmins = @($allAdmins | Where-Object { $_ -notin $breakGlassAdmins }) $gaCount = $operationalAdmins.Count $bgExcluded = $breakGlassAdmins.Count $gaStatus = if ($gaCount -ge 2 -and $gaCount -le 4) { 'Pass' } elseif ($gaCount -lt 2) { 'Fail' } else { 'Warning' } $countDetail = if ($bgExcluded -gt 0) { "$gaCount (excluding $bgExcluded break-glass)" } else { "$gaCount" } $settingParams = @{ Category = 'Admin Accounts' Setting = 'Global Administrator Count' CurrentValue = $countDetail RecommendedValue = '2-4' Status = $gaStatus CheckId = 'ENTRA-ADMIN-001' Remediation = 'Run: Get-MgDirectoryRole -Filter "displayName eq ''Global Administrator''" | Get-MgDirectoryRoleMember. Maintain 2-4 global admins using dedicated accounts (break-glass accounts are excluded from this count).' } Add-Setting @settingParams } } catch { Write-Warning "Could not check global admin count: $_" } # ------------------------------------------------------------------ # 22. Privileged Identity Management (CIS 5.3.x) -- requires Entra ID P2 # ------------------------------------------------------------------ $pimAvailable = $true $pimRoleAssignments = $null $script:pimMessage = $null # Check if tenant has P2/E5 capability for PIM $hasPimLicense = $false try { $skus = Invoke-MgGraphRequest -Method GET -Uri '/v1.0/subscribedSkus' -ErrorAction Stop $skuList = if ($skus -and $skus['value']) { @($skus['value']) } else { @() } $pimSkuIds = @( 'eec0eb4f-6444-4f95-aba0-50c24d67f998' # AAD_PREMIUM_P2 '06ebc4ee-1bb5-47dd-8120-11324bc54e06' # SPE_E5 (M365 E5) 'b05e124f-c7cc-45a0-a6aa-8cf78c946968' # EMSPREMIUM (EMS E5) 'cd2925a3-5076-4233-8931-638a8c94f773' # SPE_E5_NOPSTNCONF ) foreach ($sku in $skuList) { if ($sku['skuId'] -in $pimSkuIds -and $sku['capabilityStatus'] -eq 'Enabled') { $hasPimLicense = $true break } } } catch { Write-Verbose "Could not check SKU licenses: $_" } # Skip PIM API query entirely when no P2 license -- empty results from PIM APIs # on unlicensed tenants would be falsely interpreted as "no permanent assignments" if (-not $hasPimLicense) { $pimAvailable = $false $script:pimMessage = 'PIM not licensed (Entra ID P2 required) -- cannot verify role assignment permanence' } else { try { Write-Verbose "Checking PIM role assignments..." $graphParams = @{ Method = 'GET' Uri = '/beta/roleManagement/directory/roleAssignmentScheduleInstances' ErrorAction = 'Stop' } $pimRoleAssignments = Invoke-MgGraphRequest @graphParams } catch { if ($_.Exception.Message -match '403|Forbidden|Authorization|license') { $pimAvailable = $false $script:pimMessage = 'PIM is available but not configured in this tenant' } else { Write-Warning "Could not check PIM role assignments: $_" $pimAvailable = $false $script:pimMessage = "Could not check PIM: $($_.Exception.Message)" } } } if ($pimAvailable -and $pimRoleAssignments -and $pimRoleAssignments['value']) { # CIS 5.3.1 -- PIM manages privileged roles (no permanent GA assignments) $gaRoleTemplateId = '62e90394-69f5-4237-9190-012177145e10' $permanentGA = @($pimRoleAssignments['value'] | Where-Object { $_['roleDefinitionId'] -eq $gaRoleTemplateId -and $_['assignmentType'] -eq 'Activated' -and (-not $_['endDateTime'] -or $_['endDateTime'] -eq '9999-12-31T23:59:59Z') }) $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'PIM Manages Privileged Roles' CurrentValue = $(if ($permanentGA.Count -eq 0) { 'No permanent GA assignments' } else { "$($permanentGA.Count) permanent GA assignment(s) found" }) RecommendedValue = 'No permanent Global Admin assignments' Status = $(if ($permanentGA.Count -eq 0) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-PIM-001' Remediation = 'Entra admin center > Identity Governance > Privileged Identity Management > Azure AD roles > Global Administrator > Remove permanent active assignments. Use eligible assignments with time-bound activation.' } Add-Setting @settingParams } elseif (-not $pimAvailable) { $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'PIM Manages Privileged Roles' CurrentValue = $script:pimMessage RecommendedValue = 'PIM enabled for all privileged roles' Status = 'Review' CheckId = 'ENTRA-PIM-001' Remediation = 'This check requires Entra ID P2 (included in M365 E5). Enable PIM at Entra admin center > Identity Governance > Privileged Identity Management.' } Add-Setting @settingParams } # CIS 5.3.2/5.3.3 -- Access reviews for guests and privileged roles $accessReviews = $null if ($pimAvailable) { try { Write-Verbose "Checking access reviews..." $graphParams = @{ Method = 'GET' Uri = '/beta/identityGovernance/accessReviews/definitions?$top=100' ErrorAction = 'Stop' } $accessReviews = Invoke-MgGraphRequest @graphParams } catch { if ($_.Exception.Message -match '403|Forbidden|Authorization|license') { $pimAvailable = $false } else { Write-Warning "Could not check access reviews: $_" } } } if ($accessReviews -and $accessReviews['value']) { $allReviews = @($accessReviews['value']) # CIS 5.3.2 -- Guest access reviews $guestReviews = @($allReviews | Where-Object { $_['scope'] -and ($_['scope']['query'] -match 'guest' -or $_['scope']['@odata.type'] -match 'guest') }) $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'Access Reviews for Guest Users' CurrentValue = $(if ($guestReviews.Count -gt 0) { "$($guestReviews.Count) guest access review(s) configured" } else { 'No guest access reviews found' }) RecommendedValue = 'At least 1 access review for guests' Status = $(if ($guestReviews.Count -gt 0) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-PIM-002' Remediation = 'Entra admin center > Identity Governance > Access reviews > New access review > Review type: Guest users only. Schedule recurring reviews.' } Add-Setting @settingParams # CIS 5.3.3 -- Privileged role access reviews $roleReviews = @($allReviews | Where-Object { $_['scope'] -and ($_['scope']['query'] -match 'roleManagement|directoryRole') }) $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'Access Reviews for Privileged Roles' CurrentValue = $(if ($roleReviews.Count -gt 0) { "$($roleReviews.Count) privileged role review(s) configured" } else { 'No privileged role access reviews found' }) RecommendedValue = 'At least 1 access review for admin roles' Status = $(if ($roleReviews.Count -gt 0) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-PIM-003' Remediation = 'Entra admin center > Identity Governance > Access reviews > New access review > Review type: Members of a group or Users assigned to a privileged role.' } Add-Setting @settingParams } elseif (-not $pimAvailable) { $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'Access Reviews for Guest Users' CurrentValue = $script:pimMessage RecommendedValue = 'At least 1 access review for guests' Status = 'Review' CheckId = 'ENTRA-PIM-002' Remediation = 'This check requires Entra ID P2 (included in M365 E5). Entra admin center > Identity Governance > Access reviews.' } Add-Setting @settingParams $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'Access Reviews for Privileged Roles' CurrentValue = $script:pimMessage RecommendedValue = 'At least 1 access review for admin roles' Status = 'Review' CheckId = 'ENTRA-PIM-003' Remediation = 'This check requires Entra ID P2 (included in M365 E5). Entra admin center > Identity Governance > Access reviews.' } Add-Setting @settingParams } # CIS 5.3.4/5.3.5 -- PIM activation approval for GA and PRA $roleManagementPolicies = $null if ($pimAvailable) { try { Write-Verbose "Checking PIM role management policies..." $graphParams = @{ Method = 'GET' Uri = '/beta/policies/roleManagementPolicies?$expand=rules' ErrorAction = 'Stop' } $roleManagementPolicies = Invoke-MgGraphRequest @graphParams } catch { if ($_.Exception.Message -match '403|Forbidden|Authorization|license') { $pimAvailable = $false } else { Write-Warning "Could not check PIM policies: $_" } } } if ($roleManagementPolicies -and $roleManagementPolicies['value']) { $allPolicies = @($roleManagementPolicies['value']) # CIS 5.3.4 -- GA activation approval $gaPolicy = $allPolicies | Where-Object { $_['scopeId'] -eq '/' -and $_['scopeType'] -eq 'DirectoryRole' -and $_['displayName'] -match 'Global Administrator' } | Select-Object -First 1 $gaApprovalRequired = $false if ($gaPolicy -and $gaPolicy['rules']) { $approvalRule = $gaPolicy['rules'] | Where-Object { $_['@odata.type'] -match 'ApprovalRule' } if ($approvalRule) { $gaApprovalRequired = $approvalRule['setting']['isApprovalRequired'] } } $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'GA Activation Requires Approval' CurrentValue = $(if ($gaApprovalRequired) { 'Yes' } else { 'No' }) RecommendedValue = 'Yes' Status = $(if ($gaApprovalRequired) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-PIM-004' Remediation = 'Entra admin center > Identity Governance > PIM > Azure AD roles > Settings > Global Administrator > Require approval to activate > Yes.' } Add-Setting @settingParams # CIS 5.3.5 -- PRA activation approval $praPolicy = $allPolicies | Where-Object { $_['scopeId'] -eq '/' -and $_['scopeType'] -eq 'DirectoryRole' -and $_['displayName'] -match 'Privileged Role Administrator' } | Select-Object -First 1 $praApprovalRequired = $false if ($praPolicy -and $praPolicy['rules']) { $approvalRule = $praPolicy['rules'] | Where-Object { $_['@odata.type'] -match 'ApprovalRule' } if ($approvalRule) { $praApprovalRequired = $approvalRule['setting']['isApprovalRequired'] } } $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'PRA Activation Requires Approval' CurrentValue = $(if ($praApprovalRequired) { 'Yes' } else { 'No' }) RecommendedValue = 'Yes' Status = $(if ($praApprovalRequired) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-PIM-005' Remediation = 'Entra admin center > Identity Governance > PIM > Azure AD roles > Settings > Privileged Role Administrator > Require approval to activate > Yes.' } Add-Setting @settingParams } elseif (-not $pimAvailable) { $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'GA Activation Requires Approval' CurrentValue = $script:pimMessage RecommendedValue = 'Yes' Status = 'Review' CheckId = 'ENTRA-PIM-004' Remediation = 'This check requires Entra ID P2 (included in M365 E5). Entra admin center > Identity Governance > PIM > Azure AD roles > Settings.' } Add-Setting @settingParams $settingParams = @{ Category = 'Privileged Identity Management' Setting = 'PRA Activation Requires Approval' CurrentValue = $script:pimMessage RecommendedValue = 'Yes' Status = 'Review' CheckId = 'ENTRA-PIM-005' Remediation = 'This check requires Entra ID P2 (included in M365 E5). Entra admin center > Identity Governance > PIM > Azure AD roles > Settings.' } Add-Setting @settingParams } # ------------------------------------------------------------------ # 23. Cloud-Only Admin Accounts (CIS 1.1.1) # ------------------------------------------------------------------ try { Write-Verbose "Checking Global Administrator accounts for cloud-only status..." $gaRoleTemplateId = '62e90394-69f5-4237-9190-012177145e10' $graphParams = @{ Method = 'GET' Uri = "/v1.0/directoryRoles/roleTemplateId=$gaRoleTemplateId/members?`$select=displayName,userPrincipalName,onPremisesSyncEnabled" ErrorAction = 'Stop' } $gaMembers = Invoke-MgGraphRequest @graphParams $gaList = if ($gaMembers -and $gaMembers['value']) { @($gaMembers['value']) } else { @() } $syncedAdmins = @($gaList | Where-Object { $_['onPremisesSyncEnabled'] -eq $true }) if ($syncedAdmins.Count -eq 0) { $settingParams = @{ Category = 'Admin Accounts' Setting = 'Cloud-Only Global Admins' CurrentValue = "All $($gaList.Count) GA accounts are cloud-only" RecommendedValue = 'All admin accounts cloud-only' Status = 'Pass' CheckId = 'ENTRA-CLOUDADMIN-001' Remediation = 'No action needed.' } Add-Setting @settingParams } else { $syncedNames = ($syncedAdmins | ForEach-Object { $_['displayName'] }) -join ', ' $settingParams = @{ Category = 'Admin Accounts' Setting = 'Cloud-Only Global Admins' CurrentValue = "$($syncedAdmins.Count) synced: $syncedNames" RecommendedValue = 'All admin accounts cloud-only' Status = 'Fail' CheckId = 'ENTRA-CLOUDADMIN-001' Remediation = 'Create cloud-only admin accounts instead of using on-premises synced accounts. Entra admin center > Users > New user > Create user (cloud identity).' } Add-Setting @settingParams } } catch { Write-Warning "Could not check cloud-only admin accounts: $_" } # ------------------------------------------------------------------ # 24. Admin License Footprint (CIS 1.1.4) # ------------------------------------------------------------------ try { Write-Verbose "Checking admin account license assignments..." $gaRoleTemplateId = '62e90394-69f5-4237-9190-012177145e10' $graphParams = @{ Method = 'GET' Uri = "/v1.0/directoryRoles/roleTemplateId=$gaRoleTemplateId/members?`$select=displayName,assignedLicenses" ErrorAction = 'Stop' } $gaUsersLicense = Invoke-MgGraphRequest @graphParams # E3/E5 SKU part IDs (productivity suites that admins shouldn't have) $productivitySkus = @( '05e9a617-0261-4cee-bb36-b42c3d50e6a0', # SPE_E3 (M365 E3) '06ebc4ee-1bb5-47dd-8120-11324bc54e06', # SPE_E5 (M365 E5) '6fd2c87f-b296-42f0-b197-1e91e994b900', # ENTERPRISEPACK (O365 E3) 'c7df2760-2c81-4ef7-b578-5b5392b571df' # ENTERPRISEPREMIUM (O365 E5) ) $gaLicenseList = if ($gaUsersLicense -and $gaUsersLicense['value']) { @($gaUsersLicense['value']) } else { @() } $heavyLicensed = @($gaLicenseList | Where-Object { $licenses = $_['assignedLicenses'] $licenses | Where-Object { $productivitySkus -contains $_['skuId'] } }) if ($heavyLicensed.Count -eq 0) { $settingParams = @{ Category = 'Admin Accounts' Setting = 'Admin License Footprint' CurrentValue = 'No GA accounts have full productivity licenses' RecommendedValue = 'Admins use minimal license (Entra P2 only)' Status = 'Pass' CheckId = 'ENTRA-CLOUDADMIN-002' Remediation = 'No action needed.' } Add-Setting @settingParams } else { $names = ($heavyLicensed | ForEach-Object { $_['displayName'] }) -join ', ' $settingParams = @{ Category = 'Admin Accounts' Setting = 'Admin License Footprint' CurrentValue = "$($heavyLicensed.Count) GA with productivity license: $names" RecommendedValue = 'Admins use minimal license (Entra P2 only)' Status = 'Warning' CheckId = 'ENTRA-CLOUDADMIN-002' Remediation = 'Assign admin accounts minimal licenses (Entra ID P2). Do not assign E3/E5 productivity suites. M365 admin center > Users > Active users > Licenses.' } Add-Setting @settingParams } } catch { Write-Warning "Could not check admin license footprint: $_" } # ------------------------------------------------------------------ # 31. Entra Admin Center Access Restriction (CIS 5.1.2.4) # ------------------------------------------------------------------ try { Write-Verbose "Checking Entra admin center access restriction..." if ($authPolicy -and $null -ne $authPolicy['restrictNonAdminUsers']) { $restricted = $authPolicy['restrictNonAdminUsers'] $settingParams = @{ Category = 'Access Control' Setting = 'Entra Admin Center Restricted' CurrentValue = "$restricted" RecommendedValue = 'True' Status = $(if ($restricted) { 'Pass' } else { 'Fail' }) CheckId = 'ENTRA-ADMIN-002' Remediation = 'Entra admin center > Identity > Users > User settings > Administration center > set "Restrict access to Microsoft Entra admin center" to Yes.' } Add-Setting @settingParams } else { $settingParams = @{ Category = 'Access Control' Setting = 'Entra Admin Center Restricted' CurrentValue = 'Property not available' RecommendedValue = 'True' Status = 'Review' CheckId = 'ENTRA-ADMIN-002' Remediation = 'Entra admin center > Identity > Users > User settings > Administration center > verify "Restrict access to Microsoft Entra admin center" is set to Yes.' } Add-Setting @settingParams } } catch { Write-Warning "Could not check Entra admin center restriction: $_" } # ------------------------------------------------------------------ # 32. Emergency Access Accounts (CIS 1.1.2) # ------------------------------------------------------------------ try { Write-Verbose "Checking for emergency access (break-glass) accounts..." $graphParams = @{ Method = 'GET' Uri = "/v1.0/users?`$select=displayName,userPrincipalName,accountEnabled&`$top=999" ErrorAction = 'Stop' } $allUsers = Invoke-MgGraphRequest @graphParams $allUserList = if ($allUsers -and $allUsers['value']) { @($allUsers['value']) } else { @() } $breakGlassAccounts = Get-BreakGlassAccounts -Users $allUserList $bgCount = $breakGlassAccounts.Count $enabledBg = @($breakGlassAccounts | Where-Object { $_['accountEnabled'] -eq $true }) if ($bgCount -ge 2 -and $enabledBg.Count -ge 2) { $bgNames = ($breakGlassAccounts | ForEach-Object { $_['displayName'] }) -join ', ' $settingParams = @{ Category = 'Admin Accounts' Setting = 'Emergency Access Accounts' CurrentValue = "$bgCount found ($bgNames)" RecommendedValue = '2+ enabled break-glass accounts' Status = 'Pass' CheckId = 'ENTRA-ADMIN-003' Remediation = 'Maintain at least two cloud-only emergency access accounts excluded from all Conditional Access policies.' } Add-Setting @settingParams } else { $settingParams = @{ Category = 'Admin Accounts' Setting = 'Emergency Access Accounts' CurrentValue = "$bgCount detected (heuristic: name contains break glass/emergency)" RecommendedValue = '2+ enabled break-glass accounts' Status = 'Review' CheckId = 'ENTRA-ADMIN-003' Remediation = 'Create 2+ cloud-only emergency access accounts with Global Administrator role, excluded from all Conditional Access policies. Use naming convention including "BreakGlass" or "EmergencyAccess" for detection.' } Add-Setting @settingParams } } catch { Write-Warning "Could not check emergency access accounts: $_" } # ------------------------------------------------------------------ # 33. Admin MFA Method Strength (phishing-resistant required) # ------------------------------------------------------------------ try { Write-Verbose "Checking admin MFA method strength..." $gaRoleTemplateId = '62e90394-69f5-4237-9190-012177145e10' $graphParams = @{ Method = 'GET' Uri = "/v1.0/directoryRoles/roleTemplateId=$gaRoleTemplateId/members?`$select=id,displayName,userPrincipalName" ErrorAction = 'Stop' } $adminMembers = Invoke-MgGraphRequest @graphParams $adminList = if ($adminMembers -and $adminMembers['value']) { @($adminMembers['value']) } else { @() } if ($adminList.Count -gt 0) { $graphParams = @{ Method = 'GET' Uri = '/beta/reports/authenticationMethods/userRegistrationDetails' ErrorAction = 'Stop' } $mfaDetails = Invoke-MgGraphRequest @graphParams $mfaList = if ($mfaDetails -and $mfaDetails['value']) { @($mfaDetails['value']) } else { @() } $phishingResistantMethods = @( 'fido2' 'windowsHelloForBusiness' 'x509CertificateMultiFactor' 'passKeyDeviceBound' 'passKeyDeviceBoundAuthenticator' ) $adminIds = @($adminList | ForEach-Object { $_['id'] }) $adminMfa = @($mfaList | Where-Object { $_['id'] -in $adminIds }) $adminsWithoutPhishRes = @($adminMfa | Where-Object { $methods = @($_['methodsRegistered']) -not ($methods | Where-Object { $_ -in $phishingResistantMethods }) }) $adminsNoMfa = @($adminMfa | Where-Object { -not $_['isMfaRegistered'] }) if ($adminsNoMfa.Count -gt 0) { $names = ($adminsNoMfa | ForEach-Object { $_['userDisplayName'] }) -join ', ' $settingParams = @{ Category = 'Admin Accounts' Setting = 'Admin MFA Method Strength' CurrentValue = "$($adminsNoMfa.Count) admin(s) without MFA: $names" RecommendedValue = 'All admins use phishing-resistant MFA' Status = 'Fail' CheckId = 'ENTRA-ADMIN-004' Remediation = 'Enroll all Global Administrators in phishing-resistant MFA (FIDO2, Windows Hello for Business, or certificate-based). Entra admin center > Protection > Authentication methods > Policies.' } Add-Setting @settingParams } elseif ($adminsWithoutPhishRes.Count -gt 0) { $names = ($adminsWithoutPhishRes | ForEach-Object { $_['userDisplayName'] }) -join ', ' $settingParams = @{ Category = 'Admin Accounts' Setting = 'Admin MFA Method Strength' CurrentValue = "$($adminsWithoutPhishRes.Count) admin(s) without phishing-resistant MFA: $names" RecommendedValue = 'All admins use phishing-resistant MFA' Status = 'Warning' CheckId = 'ENTRA-ADMIN-004' Remediation = 'Upgrade admin MFA to phishing-resistant methods (FIDO2, Windows Hello for Business, or certificate-based). Standard MFA (push/TOTP) is vulnerable to adversary-in-the-middle attacks. Entra admin center > Protection > Authentication methods > Policies.' } Add-Setting @settingParams } else { $settingParams = @{ Category = 'Admin Accounts' Setting = 'Admin MFA Method Strength' CurrentValue = "All $($adminMfa.Count) admin(s) have phishing-resistant MFA" RecommendedValue = 'All admins use phishing-resistant MFA' Status = 'Pass' CheckId = 'ENTRA-ADMIN-004' Remediation = 'No action needed.' } Add-Setting @settingParams } } } catch { Write-Warning "Could not check admin MFA method strength: $_" } |