diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dfaf9f..717dd66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,13 @@ The format is based on and uses the types of changes according to [Keep a Change ### Fixed -- Fixed parameter validation for new parameters in `Invoke-M365SecurityAudit` function. +- Formatting for MgGraph tests. + +## [0.1.20] - 2024-06-30 + +### Fixed + +- Fixed parameter validation for new parameters in `Invoke-M365SecurityAudit` function ## [0.1.19] - 2024-06-30 diff --git a/source/Private/Get-CISMgOutput.ps1 b/source/Private/Get-CISMgOutput.ps1 index c5bcca8..8c6bf99 100644 --- a/source/Private/Get-CISMgOutput.ps1 +++ b/source/Private/Get-CISMgOutput.ps1 @@ -42,10 +42,12 @@ function Get-CISMgOutput { switch ($rec) { '1.1.1' { # 1.1.1 + # Test-AdministrativeAccountCompliance $AdminRoleAssignmentsAndUsers = Get-AdminRoleUserAndAssignment return $AdminRoleAssignmentsAndUsers } '1.1.3' { + # Test-GlobalAdminsCount # Step: Retrieve global admin role $globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'" # Step: Retrieve global admin members @@ -53,6 +55,7 @@ function Get-CISMgOutput { return $globalAdmins } '1.2.1' { + # Test-ManagedApprovedPublicGroups $allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility return $allGroups } @@ -67,16 +70,19 @@ function Get-CISMgOutput { return $domains } '5.1.2.3' { + # Test-RestrictTenantCreation # Retrieve the tenant creation policy $tenantCreationPolicy = (Get-MgPolicyAuthorizationPolicy).DefaultUserRolePermissions | Select-Object AllowedToCreateTenants return $tenantCreationPolicy } '5.1.8.1' { + # Test-PasswordHashSync # Retrieve password hash sync status (Condition A and C) $passwordHashSync = Get-MgOrganization | Select-Object -ExpandProperty OnPremisesSyncEnabled return $passwordHashSync } '6.1.2' { + # Test-MailboxAuditingE3 $tenantSkus = Get-MgSubscribedSku -All $e3SkuPartNumber = "SPE_E3" $founde3Sku = $tenantSkus | Where-Object { $_.SkuPartNumber -eq $e3SkuPartNumber } @@ -89,6 +95,7 @@ function Get-CISMgOutput { } } '6.1.3' { + # Test-MailboxAuditingE5 $tenantSkus = Get-MgSubscribedSku -All $e5SkuPartNumber = "SPE_E5" $founde5Sku = $tenantSkus | Where-Object { $_.SkuPartNumber -eq $e5SkuPartNumber } diff --git a/source/tests/Test-AdministrativeAccountCompliance.ps1 b/source/tests/Test-AdministrativeAccountCompliance.ps1 index 50a2605..c744408 100644 --- a/source/tests/Test-AdministrativeAccountCompliance.ps1 +++ b/source/tests/Test-AdministrativeAccountCompliance.ps1 @@ -1,7 +1,6 @@ function Test-AdministrativeAccountCompliance { [CmdletBinding()] param () - begin { # The following conditions are checked: # Condition A: The administrative account is cloud-only (not synced). @@ -11,16 +10,12 @@ function Test-AdministrativeAccountCompliance { $recnum = "1.1.1" Write-Verbose "Starting Test-AdministrativeAccountCompliance with Rec: $recnum" } - process { - try { # Retrieve admin roles, assignments, and user details including licenses Write-Verbose "Retrieving admin roles, assignments, and user details including licenses" $adminRoleAssignments = Get-CISMgOutput -Rec $recnum - $adminRoleUsers = @() - foreach ($roleName in $adminRoleAssignments.Keys) { $assignments = $adminRoleAssignments[$roleName] foreach ($assignment in $assignments) { @@ -29,21 +24,16 @@ function Test-AdministrativeAccountCompliance { $userPrincipalName = $userDetails.UserPrincipalName $licenses = $assignment.Licenses $licenseString = if ($licenses) { ($licenses.SkuPartNumber -join '|') } else { "No Licenses Found" } - # Condition A: Check if the account is cloud-only $cloudOnlyStatus = if ($userDetails.OnPremisesSyncEnabled) { "Fail" } else { "Pass" } - # Condition B: Check if the account has valid licenses $hasValidLicense = $licenses.SkuPartNumber | ForEach-Object { $validLicenses -contains $_ } $validLicensesStatus = if ($hasValidLicense) { "Pass" } else { "Fail" } - # Condition C: Check if the account has no other licenses $hasInvalidLicense = $licenses.SkuPartNumber | ForEach-Object { $validLicenses -notcontains $_ } $invalidLicenses = $licenses.SkuPartNumber | Where-Object { $validLicenses -notcontains $_ } $applicationAssignmentStatus = if ($hasInvalidLicense) { "Fail" } else { "Pass" } - Write-Verbose "User: $userPrincipalName, Cloud-Only: $cloudOnlyStatus, Valid Licenses: $validLicensesStatus, Invalid Licenses: $($invalidLicenses -join ', ')" - # Collect user information $adminRoleUsers += [PSCustomObject]@{ UserName = $userPrincipalName @@ -57,17 +47,14 @@ function Test-AdministrativeAccountCompliance { } } } - # Group admin role users by UserName and collect unique roles and licenses Write-Verbose "Grouping admin role users by UserName" $uniqueAdminRoleUsers = $adminRoleUsers | Group-Object -Property UserName | ForEach-Object { $first = $_.Group | Select-Object -First 1 $roles = ($_.Group.RoleName -join ', ') $licenses = (($_.Group | Select-Object -ExpandProperty Licenses) -join ',').Split(',') | Select-Object -Unique - $first | Select-Object UserName, UserId, HybridUser, @{Name = 'Roles'; Expression = { $roles } }, @{Name = 'Licenses'; Expression = { $licenses -join '|' } }, CloudOnlyStatus, ValidLicensesStatus, ApplicationAssignmentStatus } - # Identify non-compliant users based on conditions A, B, and C Write-Verbose "Identifying non-compliant users based on conditions" $nonCompliantUsers = $uniqueAdminRoleUsers | Where-Object { @@ -75,7 +62,6 @@ function Test-AdministrativeAccountCompliance { $_.ValidLicensesStatus -eq "Fail" -or # Fails Condition B $_.ApplicationAssignmentStatus -eq "Fail" # Fails Condition C } - # Generate failure reasons Write-Verbose "Generating failure reasons for non-compliant users" $failureReasons = $nonCompliantUsers | ForEach-Object { @@ -88,13 +74,10 @@ function Test-AdministrativeAccountCompliance { else { "Compliant Accounts: $($uniqueAdminRoleUsers.Count)" } - $result = $nonCompliantUsers.Count -eq 0 $status = if ($result) { 'Pass' } else { 'Fail' } $details = if ($nonCompliantUsers) { "Username | Roles | Cloud-Only Status | EntraID P1/P2 License Status | Other Applications Assigned Status`n$failureReasons" } else { "N/A" } - Write-Verbose "Assessment completed. Result: $status" - # Create the parameter splat $params = @{ Rec = $recnum @@ -103,7 +86,6 @@ function Test-AdministrativeAccountCompliance { Details = $details FailureReason = $failureReason } - $auditResult = Initialize-CISAuditResult @params } catch { @@ -111,7 +93,6 @@ function Test-AdministrativeAccountCompliance { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Output the result return $auditResult diff --git a/source/tests/Test-GlobalAdminsCount.ps1 b/source/tests/Test-GlobalAdminsCount.ps1 index d2804f5..e75d645 100644 --- a/source/tests/Test-GlobalAdminsCount.ps1 +++ b/source/tests/Test-GlobalAdminsCount.ps1 @@ -4,7 +4,6 @@ function Test-GlobalAdminsCount { param ( # Define your parameters here if needed ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 @@ -23,23 +22,19 @@ function Test-GlobalAdminsCount { # - Condition A: The number of global admins is less than 2. # - Condition B: The number of global admins is more than 4. # - Condition C: Any discrepancies or errors in retrieving the list of global admin usernames. - # Initialization code, if needed $recnum = "1.1.3" + Write-Verbose "Starting Test-GlobalAdminsCount with Rec: $recnum" } - process { try { $globalAdmins = Get-CISMgOutput -Rec $recnum - # Step: Count the number of global admins $globalAdminCount = $globalAdmins.Count - # Step: Retrieve and format the usernames of global admins $globalAdminUsernames = ($globalAdmins | ForEach-Object { "$($_.AdditionalProperties["displayName"]) ($($_.AdditionalProperties["userPrincipalName"]))" }) -join ', ' - # Step: Determine failure reasons based on global admin count $failureReasons = if ($globalAdminCount -lt 2) { "Less than 2 global admins: $globalAdminUsernames" @@ -50,10 +45,8 @@ function Test-GlobalAdminsCount { else { "N/A" } - # Step: Prepare details for the audit result $details = "Count: $globalAdminCount; Users: $globalAdminUsernames" - # Step: Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -69,7 +62,6 @@ function Test-GlobalAdminsCount { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return the audit result return $auditResult diff --git a/source/tests/Test-ManagedApprovedPublicGroups.ps1 b/source/tests/Test-ManagedApprovedPublicGroups.ps1 index 944b47e..4903afe 100644 --- a/source/tests/Test-ManagedApprovedPublicGroups.ps1 +++ b/source/tests/Test-ManagedApprovedPublicGroups.ps1 @@ -4,14 +4,12 @@ function Test-ManagedApprovedPublicGroups { param ( # Parameters can be added if needed ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 - # Initialization code, if needed $recnum = "1.2.1" - + Write-Verbose "Starting Test-ManagedApprovedPublicGroups with Rec: $recnum" # Conditions for 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated) # # Validate test for a pass: @@ -26,12 +24,10 @@ function Test-ManagedApprovedPublicGroups { # - Condition A: One or more groups have the status 'Public' in the privacy column on the Active teams and groups page. # - Condition B: Using Microsoft Graph PowerShell, one or more groups return a status of 'Public' when checked. } - process { try { # Step: Retrieve all groups with visibility set to 'Public' $allGroups = Get-CISMgOutput -Rec $recnum - # Step: Determine failure reasons based on the presence of public groups $failureReasons = if ($null -ne $allGroups -and $allGroups.Count -gt 0) { "There are public groups present that are not organizationally managed/approved." @@ -39,7 +35,6 @@ function Test-ManagedApprovedPublicGroups { else { "N/A" } - # Step: Prepare details for the audit result $details = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { "No public groups found." @@ -48,7 +43,6 @@ function Test-ManagedApprovedPublicGroups { $groupDetails = $allGroups | ForEach-Object { $_.DisplayName + " (" + $_.Visibility + ")" } "Public groups found: $($groupDetails -join ', ')" } - # Step: Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -64,7 +58,6 @@ function Test-ManagedApprovedPublicGroups { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return the audit result return $auditResult diff --git a/source/tests/Test-PasswordHashSync.ps1 b/source/tests/Test-PasswordHashSync.ps1 index d131a3e..eb14f2d 100644 --- a/source/tests/Test-PasswordHashSync.ps1 +++ b/source/tests/Test-PasswordHashSync.ps1 @@ -5,7 +5,6 @@ function Test-PasswordHashSync { # Aligned # Parameters can be added if needed ) - begin { # Conditions for 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments # @@ -22,21 +21,18 @@ function Test-PasswordHashSync { # - Condition A: Password hash sync is not enabled in the Azure AD Connect tool on the on-premises server. # - Condition B: Password hash sync is not verified as enabled in the Azure AD Connect Sync section in the Microsoft Entra admin center. # - Condition C: Using Microsoft Graph PowerShell, the verification command returns no result indicating that password sync is not enabled for the on-premises AD. - # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "5.1.8.1" + Write-Verbose "Starting Test-PasswordHashSync with Rec: $recnum" } - process { try { # 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments - # Retrieve password hash sync status (Condition A and C) $passwordHashSync = Get-CISMgOutput -Rec $recnum $hashSyncResult = $passwordHashSync - # Prepare failure reasons and details based on compliance $failureReasons = if (-not $hashSyncResult) { "Password hash sync for hybrid deployments is not enabled" @@ -44,9 +40,7 @@ function Test-PasswordHashSync { else { "N/A" } - $details = "OnPremisesSyncEnabled: $($passwordHashSync)" - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -62,9 +56,8 @@ function Test-PasswordHashSync { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return the audit result return $auditResult } -} +} \ No newline at end of file diff --git a/source/tests/Test-RestrictTenantCreation.ps1 b/source/tests/Test-RestrictTenantCreation.ps1 index b6f5382..4f34647 100644 --- a/source/tests/Test-RestrictTenantCreation.ps1 +++ b/source/tests/Test-RestrictTenantCreation.ps1 @@ -5,23 +5,19 @@ function Test-RestrictTenantCreation { # Aligned # Parameters can be added if needed ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 - # Initialization code, if needed $recnum = "5.1.2.3" - + Write-Verbose "Starting Test-RestrictTenantCreation with Rec: $recnum" <# Conditions for 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes' - Validate test for a pass: - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. - Specific conditions to check: - Condition A: Restrict non-admin users from creating tenants is set to 'Yes' in the Azure AD and Entra administration portal. - Condition B: Using PowerShell, the setting for restricting non-admin users from creating tenants is set to 'Yes'. - Validate test for a fail: - Confirm that the failure conditions in the automated test are consistent with the manual audit results. - Specific conditions to check: @@ -29,15 +25,12 @@ function Test-RestrictTenantCreation { - Condition B: Using PowerShell, the setting for restricting non-admin users from creating tenants is not set to 'Yes'. #> } - process { try { # 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes' - # Retrieve the tenant creation policy $tenantCreationPolicy = Get-CISMgOutput -Rec $recnum $tenantCreationResult = -not $tenantCreationPolicy.AllowedToCreateTenants - # Prepare failure reasons and details based on compliance $failureReasons = if ($tenantCreationResult) { "N/A" @@ -45,9 +38,7 @@ function Test-RestrictTenantCreation { else { "Non-admin users can create tenants" } - $details = "AllowedToCreateTenants: $($tenantCreationPolicy.AllowedToCreateTenants)" - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -63,9 +54,8 @@ function Test-RestrictTenantCreation { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return the audit result return $auditResult } -} +} \ No newline at end of file