Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
be0b6e0129 | ||
|
642cdfe2ab | ||
|
a8b76c7e16 | ||
|
fbf40fa98e | ||
|
f409e8a5f1 | ||
|
c341279531 | ||
|
6a8438bbe8 | ||
|
87c635210d | ||
|
07592569b4 | ||
|
4b3a0b7505 | ||
|
042bf7b37c | ||
|
69ae64562f | ||
|
c64325e773 | ||
|
c341db53c5 | ||
|
2f5c653cc8 | ||
|
00600123f3 | ||
|
0cb1643341 | ||
|
939980b087 | ||
|
f375fdd5ef | ||
|
0ea930c708 | ||
|
f9e3b5faed | ||
|
4613d592d1 | ||
|
da968db3e2 | ||
|
357f284d08 | ||
|
9e3058add4 | ||
|
d7d16ff0b5 | ||
|
45eb961554 | ||
|
686e805f6a | ||
|
63edc13261 | ||
|
9508130ddd | ||
|
db73d755ed |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,3 +17,4 @@ node_modules
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
Aligned.xlsx
|
Aligned.xlsx
|
||||||
test-gh1.ps1
|
test-gh1.ps1
|
||||||
|
ModdedModules/*
|
25
CHANGELOG.md
25
CHANGELOG.md
@@ -6,6 +6,31 @@ The format is based on and uses the types of changes according to [Keep a Change
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- Get-SPOSite command to return all but voided output for no code runs (Ex: PowerAutomate)
|
||||||
|
|
||||||
|
## [0.1.27] - 2025-01-13
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added additional error handling to connect function to identify problematic steps when they occur.
|
||||||
|
- Added new method of verifying spo tenant for Connect-SPOService branch of connect function.
|
||||||
|
- Added method to avoid "assembly already loaded" error in PNP Powershell function on first run, subsequent runs in the same session will still throw the error.
|
||||||
|
|
||||||
|
## [0.1.26] - 2024-08-04
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added `New-M365SecurityAuditAuthObject` function to create a new authentication object for the security audit for app-based authentication.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Changed authentication options to include parameter for authenticating with a certificate.
|
||||||
|
- Changed verbose output to ensure methods for suppressing all forms of output are available.
|
||||||
|
|
||||||
|
## [0.1.25] - 2024-07-23
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
- Fixed test 1.3.1 as notification window for password expiration is no longer required.
|
- Fixed test 1.3.1 as notification window for password expiration is no longer required.
|
||||||
|
|
||||||
## [0.1.24] - 2024-07-07
|
## [0.1.24] - 2024-07-07
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
# M365FoundationsCISReport Module
|
# M365FoundationsCISReport Module
|
||||||
|
[](https://github.com/CriticalSolutionsNetwork/M365FoundationsCISReport/actions/workflows/powershell.yml)
|
||||||
|
[](https://github.com/CriticalSolutionsNetwork/M365FoundationsCISReport/actions/workflows/pages/pages-build-deployment)
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This PowerShell module is based on CIS benchmarks and is distributed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. This means:
|
This PowerShell module is based on CIS benchmarks and is distributed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. This means:
|
||||||
@@ -17,19 +18,47 @@ For full license details, please visit [Creative Commons Attribution-NonCommerci
|
|||||||
3. [Get-AdminRoleUserLicense](#Get-AdminRoleUserLicense)
|
3. [Get-AdminRoleUserLicense](#Get-AdminRoleUserLicense)
|
||||||
4. [Get-MFAStatus](#Get-MFAStatus)
|
4. [Get-MFAStatus](#Get-MFAStatus)
|
||||||
5. [Grant-M365SecurityAuditConsent](#Grant-M365SecurityAuditConsent)
|
5. [Grant-M365SecurityAuditConsent](#Grant-M365SecurityAuditConsent)
|
||||||
6. [Remove-RowsWithEmptyCSVStatus](#Remove-RowsWithEmptyCSVStatus)
|
6. [New-M365SecurityAuditAuthObject](#New-M365SecurityAuditAuthObject)
|
||||||
7. [Sync-CISExcelAndCsvData](#Sync-CISExcelAndCsvData)
|
7. [Remove-RowsWithEmptyCSVStatus](#Remove-RowsWithEmptyCSVStatus)
|
||||||
|
8. [Sync-CISExcelAndCsvData](#Sync-CISExcelAndCsvData)
|
||||||
|
|
||||||
## Invoke-M365SecurityAudit
|
## Module Dependencies
|
||||||
|
|
||||||
|
The `M365FoundationsCISReport` module relies on several other PowerShell modules to perform its operations. The default run ensures these modules are installed with the specified versions. Use -NoModuleCheck to skip this step if you have installed the required modules previously and would like to suppress any output for automated runs.
|
||||||
|
|
||||||
|
### Required Modules for Audit Functions
|
||||||
|
|
||||||
|
Default modules used for audit functions:
|
||||||
|
|
||||||
|
- **ExchangeOnlineManagement**
|
||||||
|
- Required Version: `3.3.0`
|
||||||
|
|
||||||
|
- **Microsoft.Graph**
|
||||||
|
- Required Version: `2.4.0`
|
||||||
|
|
||||||
|
- **PnP.PowerShell** (Optional, if PnP App authentication is used for SharePoint Online)
|
||||||
|
- Required Version: `2.5.0`
|
||||||
|
|
||||||
|
- **Microsoft.Online.SharePoint.PowerShell** (If PnP authentication is not used (Default) )
|
||||||
|
- Required Version: `16.0.24009.12000`
|
||||||
|
|
||||||
|
- **MicrosoftTeams**
|
||||||
|
- Required Version: `5.5.0`
|
||||||
|
|
||||||
|
- **ImportExcel** (If importing or exporting Excel files)
|
||||||
|
- Required Version: `7.8.9`
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Example 1: Performing a security audit based on CIS benchmarks
|
# Example 1: Performing a security audit based on CIS benchmarks
|
||||||
$auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com"
|
$auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com"
|
||||||
$auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com" -ApprovedCloudStorageProviders "DropBox" -ApprovedFederatedDomains "northwind.com"
|
$auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com" -ApprovedCloudStorageProviders "DropBox" -ApprovedFederatedDomains "northwind.com"
|
||||||
|
# Suppressed output for automated runs
|
||||||
|
$auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -NoModuleCheck -NoModuleCheck -DoNotConfirmConnections -Confirm:$false
|
||||||
|
|
||||||
# Example 2: Exporting a security audit and it's nested tables to zipped CSV files
|
# Example 2: Exporting a security audit and it's nested tables to zipped CSV files
|
||||||
Export-M365SecurityAuditTable -AuditResults $auditResults -ExportPath "C:\temp" -ExportOriginalTests -ExportAllTests
|
Export-M365SecurityAuditTable -AuditResults $auditResults -ExportPath "C:\temp" -ExportOriginalTests -ExportNestedTables
|
||||||
# Output Ex: 2024.07.07_14.55.55_M365FoundationsAudit_368B2E2F.zip
|
# Output Ex: 2024.07.07_14.55.55_M365FoundationsAudit_368B2E2F.zip
|
||||||
|
|
||||||
# Example 3: Retrieving licenses for users in administrative roles
|
# Example 3: Retrieving licenses for users in administrative roles
|
||||||
@@ -46,6 +75,15 @@ Sync-CISExcelAndCsvData -ExcelPath "path\to\excel.xlsx" -CsvPath "path\to\data.c
|
|||||||
|
|
||||||
# Example 7: Granting Microsoft Graph permissions to the auditor
|
# Example 7: Granting Microsoft Graph permissions to the auditor
|
||||||
Grant-M365SecurityAuditConsent -UserPrincipalNameForConsent 'user@example.com'
|
Grant-M365SecurityAuditConsent -UserPrincipalNameForConsent 'user@example.com'
|
||||||
|
|
||||||
|
# Example 8: (PowerShell 7.x Only) Creating a new authentication object for the security audit for app-based authentication.
|
||||||
|
$authParams = New-M365SecurityAuditAuthObject `
|
||||||
|
-ClientCertThumbPrint "ABCDEF1234567890ABCDEF1234567890ABCDEF12" `
|
||||||
|
-ClientId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-TenantId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-OnMicrosoftUrl "yourcompany.onmicrosoft.com" `
|
||||||
|
-SpAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
|
Invoke-M365SecurityAudit -AuthParams $authParams -TenantAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
```
|
```
|
||||||
|
|
||||||
# NOTE
|
# NOTE
|
||||||
|
BIN
docs/index.html
BIN
docs/index.html
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
external help file: M365FoundationsCISReport-help.xml
|
external help file: M365FoundationsCISReport-help.xml
|
||||||
Module Name: M365FoundationsCISReport
|
Module Name: M365FoundationsCISReport
|
||||||
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Export-M365SecurityAuditTable
|
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Export-M365SecurityAuditTable
|
||||||
@@ -15,24 +15,27 @@ Exports M365 security audit results to a CSV file or outputs a specific test res
|
|||||||
### OutputObjectFromAuditResultsSingle
|
### OutputObjectFromAuditResultsSingle
|
||||||
```
|
```
|
||||||
Export-M365SecurityAuditTable [-AuditResults] <CISAuditResult[]> [-OutputTestNumber] <String>
|
Export-M365SecurityAuditTable [-AuditResults] <CISAuditResult[]> [-OutputTestNumber] <String>
|
||||||
[<CommonParameters>]
|
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
### ExportAllResultsFromAuditResults
|
### ExportAllResultsFromAuditResults
|
||||||
```
|
```
|
||||||
Export-M365SecurityAuditTable [-AuditResults] <CISAuditResult[]> [-ExportAllTests] -ExportPath <String>
|
Export-M365SecurityAuditTable [-AuditResults] <CISAuditResult[]> [-ExportNestedTables] -ExportPath <String>
|
||||||
[-ExportOriginalTests] [-ExportToExcel] [<CommonParameters>]
|
[-ExportOriginalTests] [-ExportToExcel] [-Prefix <String>] [-ProgressAction <ActionPreference>] [-WhatIf]
|
||||||
|
[-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
### OutputObjectFromCsvSingle
|
### OutputObjectFromCsvSingle
|
||||||
```
|
```
|
||||||
Export-M365SecurityAuditTable [-CsvPath] <String> [-OutputTestNumber] <String> [<CommonParameters>]
|
Export-M365SecurityAuditTable [-CsvPath] <String> [-OutputTestNumber] <String>
|
||||||
|
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
### ExportAllResultsFromCsv
|
### ExportAllResultsFromCsv
|
||||||
```
|
```
|
||||||
Export-M365SecurityAuditTable [-CsvPath] <String> [-ExportAllTests] -ExportPath <String> [-ExportOriginalTests]
|
Export-M365SecurityAuditTable [-CsvPath] <String> [-ExportNestedTables] -ExportPath <String>
|
||||||
[-ExportToExcel] [<CommonParameters>]
|
[-ExportOriginalTests] [-ExportToExcel] [-Prefix <String>] [-ProgressAction <ActionPreference>] [-WhatIf]
|
||||||
|
[-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
@@ -109,8 +112,24 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -ExportAllTests
|
### -OutputTestNumber
|
||||||
Switch to export all test results.
|
The test number to output as an object.
|
||||||
|
Valid values are "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4".
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: OutputObjectFromAuditResultsSingle, OutputObjectFromCsvSingle
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: 2
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -ExportNestedTables
|
||||||
|
Switch to export all test results. When specified, all test results are exported to the specified path.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: SwitchParameter
|
Type: SwitchParameter
|
||||||
@@ -124,21 +143,6 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -ExportOriginalTests
|
|
||||||
Switch to export the original audit results to a CSV file.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
Type: SwitchParameter
|
|
||||||
Parameter Sets: ExportAllResultsFromAuditResults, ExportAllResultsFromCsv
|
|
||||||
Aliases:
|
|
||||||
|
|
||||||
Required: True
|
|
||||||
Position: Named
|
|
||||||
Default value: False
|
|
||||||
Accept pipeline input: False
|
|
||||||
Accept wildcard characters: False
|
|
||||||
```
|
|
||||||
|
|
||||||
### -ExportPath
|
### -ExportPath
|
||||||
The path where the CSV files will be exported.
|
The path where the CSV files will be exported.
|
||||||
|
|
||||||
@@ -154,6 +158,21 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### -ExportOriginalTests
|
||||||
|
Switch to export the original audit results to a CSV file.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: ExportAllResultsFromAuditResults, ExportAllResultsFromCsv
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: False
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
### -ExportToExcel
|
### -ExportToExcel
|
||||||
Switch to export the results to an Excel file.
|
Switch to export the results to an Excel file.
|
||||||
|
|
||||||
@@ -169,17 +188,62 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -OutputTestNumber
|
### -Prefix
|
||||||
The test number to output as an object.
|
Add Prefix to filename after date when outputting to excel or csv.
|
||||||
Valid values are "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4".
|
Validate that the count of letters in the prefix is less than 5.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: String
|
Type: String
|
||||||
Parameter Sets: OutputObjectFromAuditResultsSingle, OutputObjectFromCsvSingle
|
Parameter Sets: ExportAllResultsFromAuditResults, ExportAllResultsFromCsv
|
||||||
Aliases:
|
Aliases:
|
||||||
|
|
||||||
Required: True
|
Required: False
|
||||||
Position: 2
|
Position: Named
|
||||||
|
Default value: Corp
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -WhatIf
|
||||||
|
Shows what would happen if the cmdlet runs. The cmdlet is not run.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: wi
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -Confirm
|
||||||
|
Prompts you for confirmation before running the cmdlet.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: cf
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -ProgressAction
|
||||||
|
{{ Fill ProgressAction Description }}
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: ActionPreference
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: proga
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
Default value: None
|
Default value: None
|
||||||
Accept pipeline input: False
|
Accept pipeline input: False
|
||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
external help file: M365FoundationsCISReport-help.xml
|
external help file: M365FoundationsCISReport-help.xml
|
||||||
Module Name: M365FoundationsCISReport
|
Module Name: M365FoundationsCISReport
|
||||||
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Get-AdminRoleUserLicense
|
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Get-AdminRoleUserLicense
|
||||||
@@ -13,7 +13,7 @@ Retrieves user licenses and roles for administrative accounts from Microsoft 365
|
|||||||
## SYNTAX
|
## SYNTAX
|
||||||
|
|
||||||
```
|
```
|
||||||
Get-AdminRoleUserLicense [-SkipGraphConnection] [<CommonParameters>]
|
Get-AdminRoleUserLicense [-SkipGraphConnection] [-ProgressAction <ActionPreference>] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
@@ -54,6 +54,21 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### -ProgressAction
|
||||||
|
{{ Fill ProgressAction Description }}
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: ActionPreference
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: proga
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
### CommonParameters
|
### CommonParameters
|
||||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
external help file: M365FoundationsCISReport-help.xml
|
external help file: M365FoundationsCISReport-help.xml
|
||||||
Module Name: M365FoundationsCISReport
|
Module Name: M365FoundationsCISReport
|
||||||
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Get-MFAStatus
|
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Get-MFAStatus
|
||||||
@@ -13,7 +13,8 @@ Retrieves the MFA (Multi-Factor Authentication) status for Azure Active Director
|
|||||||
## SYNTAX
|
## SYNTAX
|
||||||
|
|
||||||
```
|
```
|
||||||
Get-MFAStatus [[-UserId] <String>] [-SkipMSOLConnectionChecks] [<CommonParameters>]
|
Get-MFAStatus [[-UserId] <String>] [-SkipMSOLConnectionChecks] [-ProgressAction <ActionPreference>]
|
||||||
|
[<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
@@ -36,6 +37,22 @@ Retrieves the MFA status for the specified user with the UPN "example@domain.com
|
|||||||
|
|
||||||
## PARAMETERS
|
## PARAMETERS
|
||||||
|
|
||||||
|
### -UserId
|
||||||
|
The User Principal Name (UPN) of a specific user to retrieve MFA status for.
|
||||||
|
If not provided, the function retrieves MFA status for all users.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: 1
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
### -SkipMSOLConnectionChecks
|
### -SkipMSOLConnectionChecks
|
||||||
{{ Fill SkipMSOLConnectionChecks Description }}
|
{{ Fill SkipMSOLConnectionChecks Description }}
|
||||||
|
|
||||||
@@ -51,17 +68,16 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -UserId
|
### -ProgressAction
|
||||||
The User Principal Name (UPN) of a specific user to retrieve MFA status for.
|
{{ Fill ProgressAction Description }}
|
||||||
If not provided, the function retrieves MFA status for all users.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: String
|
Type: ActionPreference
|
||||||
Parameter Sets: (All)
|
Parameter Sets: (All)
|
||||||
Aliases:
|
Aliases: proga
|
||||||
|
|
||||||
Required: False
|
Required: False
|
||||||
Position: 1
|
Position: Named
|
||||||
Default value: None
|
Default value: None
|
||||||
Accept pipeline input: False
|
Accept pipeline input: False
|
||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
external help file: M365FoundationsCISReport-help.xml
|
external help file: M365FoundationsCISReport-help.xml
|
||||||
Module Name: M365FoundationsCISReport
|
Module Name: M365FoundationsCISReport
|
||||||
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Grant-M365SecurityAuditConsent
|
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Grant-M365SecurityAuditConsent
|
||||||
@@ -14,7 +14,8 @@ Grants Microsoft Graph permissions for an auditor.
|
|||||||
|
|
||||||
```
|
```
|
||||||
Grant-M365SecurityAuditConsent [-UserPrincipalNameForConsent] <String> [-SkipGraphConnection]
|
Grant-M365SecurityAuditConsent [-UserPrincipalNameForConsent] <String> [-SkipGraphConnection]
|
||||||
[-SkipModuleCheck] [-SuppressRevertOutput] [-DoNotDisconnect] [-WhatIf] [-Confirm] [<CommonParameters>]
|
[-SkipModuleCheck] [-SuppressRevertOutput] [-DoNotDisconnect] [-ProgressAction <ActionPreference>] [-WhatIf]
|
||||||
|
[-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
@@ -40,18 +41,18 @@ Grants Microsoft Graph permissions to user@example.com, skipping the connection
|
|||||||
|
|
||||||
## PARAMETERS
|
## PARAMETERS
|
||||||
|
|
||||||
### -DoNotDisconnect
|
### -UserPrincipalNameForConsent
|
||||||
If specified, does not disconnect from Microsoft Graph after granting consent.
|
Specify the UPN of the user to grant consent for.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: SwitchParameter
|
Type: String
|
||||||
Parameter Sets: (All)
|
Parameter Sets: (All)
|
||||||
Aliases:
|
Aliases:
|
||||||
|
|
||||||
Required: False
|
Required: True
|
||||||
Position: Named
|
Position: 1
|
||||||
Default value: False
|
Default value: None
|
||||||
Accept pipeline input: False
|
Accept pipeline input: True (ByPropertyName, ByValue)
|
||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -100,18 +101,34 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -UserPrincipalNameForConsent
|
### -DoNotDisconnect
|
||||||
Specify the UPN of the user to grant consent for.
|
If specified, does not disconnect from Microsoft Graph after granting consent.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: String
|
Type: SwitchParameter
|
||||||
Parameter Sets: (All)
|
Parameter Sets: (All)
|
||||||
Aliases:
|
Aliases:
|
||||||
|
|
||||||
Required: True
|
Required: False
|
||||||
Position: 1
|
Position: Named
|
||||||
|
Default value: False
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -WhatIf
|
||||||
|
Shows what would happen if the cmdlet runs.
|
||||||
|
The cmdlet is not run.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: wi
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
Default value: None
|
Default value: None
|
||||||
Accept pipeline input: True (ByPropertyName, ByValue)
|
Accept pipeline input: False
|
||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -130,14 +147,13 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -WhatIf
|
### -ProgressAction
|
||||||
Shows what would happen if the cmdlet runs.
|
{{ Fill ProgressAction Description }}
|
||||||
The cmdlet is not run.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: SwitchParameter
|
Type: ActionPreference
|
||||||
Parameter Sets: (All)
|
Parameter Sets: (All)
|
||||||
Aliases: wi
|
Aliases: proga
|
||||||
|
|
||||||
Required: False
|
Required: False
|
||||||
Position: Named
|
Position: Named
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
external help file: M365FoundationsCISReport-help.xml
|
external help file: M365FoundationsCISReport-help.xml
|
||||||
Module Name: M365FoundationsCISReport
|
Module Name: M365FoundationsCISReport
|
||||||
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Invoke-M365SecurityAudit
|
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Invoke-M365SecurityAudit
|
||||||
@@ -16,14 +16,16 @@ Invokes a security audit for Microsoft 365 environments.
|
|||||||
```
|
```
|
||||||
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>]
|
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>]
|
||||||
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
||||||
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-WhatIf] [-Confirm] [<CommonParameters>]
|
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-AuthParams <CISAuthenticationParameters>]
|
||||||
|
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
### ELevelFilter
|
### ELevelFilter
|
||||||
```
|
```
|
||||||
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] -ELevel <String>
|
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] -ELevel <String>
|
||||||
-ProfileLevel <String> [-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>]
|
-ProfileLevel <String> [-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>]
|
||||||
[-DoNotConnect] [-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-WhatIf] [-Confirm]
|
[-DoNotConnect] [-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections]
|
||||||
|
[-AuthParams <CISAuthenticationParameters>] [-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm]
|
||||||
[<CommonParameters>]
|
[<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -31,35 +33,40 @@ Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] -ELev
|
|||||||
```
|
```
|
||||||
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] [-IncludeIG1]
|
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] [-IncludeIG1]
|
||||||
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
||||||
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-WhatIf] [-Confirm] [<CommonParameters>]
|
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-AuthParams <CISAuthenticationParameters>]
|
||||||
|
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
### IG2Filter
|
### IG2Filter
|
||||||
```
|
```
|
||||||
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] [-IncludeIG2]
|
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] [-IncludeIG2]
|
||||||
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
||||||
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-WhatIf] [-Confirm] [<CommonParameters>]
|
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-AuthParams <CISAuthenticationParameters>]
|
||||||
|
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
### IG3Filter
|
### IG3Filter
|
||||||
```
|
```
|
||||||
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] [-IncludeIG3]
|
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] [-IncludeIG3]
|
||||||
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
||||||
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-WhatIf] [-Confirm] [<CommonParameters>]
|
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-AuthParams <CISAuthenticationParameters>]
|
||||||
|
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
### RecFilter
|
### RecFilter
|
||||||
```
|
```
|
||||||
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] -IncludeRecommendation <String[]>
|
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] -IncludeRecommendation <String[]>
|
||||||
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
||||||
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-WhatIf] [-Confirm] [<CommonParameters>]
|
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-AuthParams <CISAuthenticationParameters>]
|
||||||
|
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
### SkipRecFilter
|
### SkipRecFilter
|
||||||
```
|
```
|
||||||
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] -SkipRecommendation <String[]>
|
Invoke-M365SecurityAudit [-TenantAdminUrl <String>] [-DomainName <String>] -SkipRecommendation <String[]>
|
||||||
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
[-ApprovedCloudStorageProviders <String[]>] [-ApprovedFederatedDomains <String[]>] [-DoNotConnect]
|
||||||
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-WhatIf] [-Confirm] [<CommonParameters>]
|
[-DoNotDisconnect] [-NoModuleCheck] [-DoNotConfirmConnections] [-AuthParams <CISAuthenticationParameters>]
|
||||||
|
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
@@ -165,26 +172,12 @@ What if: Performing the operation "Invoke-M365SecurityAudit" on target "Microsof
|
|||||||
|
|
||||||
## PARAMETERS
|
## PARAMETERS
|
||||||
|
|
||||||
### -ApprovedCloudStorageProviders
|
### -TenantAdminUrl
|
||||||
Specifies the approved cloud storage providers for the audit. Accepts an array of cloud storage provider names.
|
The URL of the tenant admin.
|
||||||
|
If not specified, none of the SharePoint Online tests will run.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: String[]
|
Type: String
|
||||||
Parameter Sets: (All)
|
|
||||||
Aliases:
|
|
||||||
|
|
||||||
Required: False
|
|
||||||
Position: Named
|
|
||||||
Default value: @()
|
|
||||||
Accept pipeline input: False
|
|
||||||
Accept wildcard characters: False
|
|
||||||
```
|
|
||||||
|
|
||||||
### -ApprovedFederatedDomains
|
|
||||||
Specifies the approved federated domains for the audit test 8.2.1. Accepts an array of allowed domain names.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
Type: String[]
|
|
||||||
Parameter Sets: (All)
|
Parameter Sets: (All)
|
||||||
Aliases:
|
Aliases:
|
||||||
|
|
||||||
@@ -210,51 +203,6 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -DoNotConfirmConnections
|
|
||||||
If specified, the cmdlet will not prompt for confirmation before proceeding with established connections and will disconnect from all of them.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
Type: SwitchParameter
|
|
||||||
Parameter Sets: (All)
|
|
||||||
Aliases:
|
|
||||||
|
|
||||||
Required: False
|
|
||||||
Position: Named
|
|
||||||
Default value: False
|
|
||||||
Accept pipeline input: False
|
|
||||||
Accept wildcard characters: False
|
|
||||||
```
|
|
||||||
|
|
||||||
### -DoNotConnect
|
|
||||||
If specified, the cmdlet will not establish a connection to Microsoft 365 services.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
Type: SwitchParameter
|
|
||||||
Parameter Sets: (All)
|
|
||||||
Aliases:
|
|
||||||
|
|
||||||
Required: False
|
|
||||||
Position: Named
|
|
||||||
Default value: False
|
|
||||||
Accept pipeline input: False
|
|
||||||
Accept wildcard characters: False
|
|
||||||
```
|
|
||||||
|
|
||||||
### -DoNotDisconnect
|
|
||||||
If specified, the cmdlet will not disconnect from Microsoft 365 services after execution.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
Type: SwitchParameter
|
|
||||||
Parameter Sets: (All)
|
|
||||||
Aliases:
|
|
||||||
|
|
||||||
Required: False
|
|
||||||
Position: Named
|
|
||||||
Default value: False
|
|
||||||
Accept pipeline input: False
|
|
||||||
Accept wildcard characters: False
|
|
||||||
```
|
|
||||||
|
|
||||||
### -ELevel
|
### -ELevel
|
||||||
Specifies the E-Level (E3 or E5) for the audit.
|
Specifies the E-Level (E3 or E5) for the audit.
|
||||||
This parameter is optional and can be combined with the ProfileLevel parameter.
|
This parameter is optional and can be combined with the ProfileLevel parameter.
|
||||||
@@ -271,6 +219,22 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### -ProfileLevel
|
||||||
|
Specifies the profile level (L1 or L2) for the audit.
|
||||||
|
This parameter is optional and can be combined with the ELevel parameter.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: ELevelFilter
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
### -IncludeIG1
|
### -IncludeIG1
|
||||||
If specified, includes tests where IG1 is true.
|
If specified, includes tests where IG1 is true.
|
||||||
|
|
||||||
@@ -332,37 +296,6 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -NoModuleCheck
|
|
||||||
If specified, the cmdlet will not check for the presence of required modules.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
Type: SwitchParameter
|
|
||||||
Parameter Sets: (All)
|
|
||||||
Aliases:
|
|
||||||
|
|
||||||
Required: False
|
|
||||||
Position: Named
|
|
||||||
Default value: False
|
|
||||||
Accept pipeline input: False
|
|
||||||
Accept wildcard characters: False
|
|
||||||
```
|
|
||||||
|
|
||||||
### -ProfileLevel
|
|
||||||
Specifies the profile level (L1 or L2) for the audit.
|
|
||||||
This parameter is optional and can be combined with the ELevel parameter.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
Type: String
|
|
||||||
Parameter Sets: ELevelFilter
|
|
||||||
Aliases:
|
|
||||||
|
|
||||||
Required: True
|
|
||||||
Position: Named
|
|
||||||
Default value: None
|
|
||||||
Accept pipeline input: False
|
|
||||||
Accept wildcard characters: False
|
|
||||||
```
|
|
||||||
|
|
||||||
### -SkipRecommendation
|
### -SkipRecommendation
|
||||||
Specifies specific recommendations to exclude from the audit.
|
Specifies specific recommendations to exclude from the audit.
|
||||||
Accepts an array of recommendation numbers.
|
Accepts an array of recommendation numbers.
|
||||||
@@ -379,15 +312,120 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -TenantAdminUrl
|
### -ApprovedCloudStorageProviders
|
||||||
The URL of the tenant admin.
|
Specifies the approved cloud storage providers for the audit. Accepts an array of cloud storage provider names.
|
||||||
If not specified, none of the SharePoint Online tests will run.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: String
|
Type: String[]
|
||||||
Parameter Sets: (All)
|
Parameter Sets: (All)
|
||||||
Aliases:
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: @()
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -ApprovedFederatedDomains
|
||||||
|
Specifies the approved federated domains for the audit test 8.2.1. Accepts an array of allowed domain names.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String[]
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -DoNotConnect
|
||||||
|
If specified, the cmdlet will not establish a connection to Microsoft 365 services.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: False
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -DoNotDisconnect
|
||||||
|
If specified, the cmdlet will not disconnect from Microsoft 365 services after execution.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: False
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -NoModuleCheck
|
||||||
|
If specified, the cmdlet will not check for the presence of required modules.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: False
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -DoNotConfirmConnections
|
||||||
|
If specified, the cmdlet will not prompt for confirmation before proceeding with established connections and will disconnect from all of them.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: False
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -AuthParams
|
||||||
|
Specifies an authentication object containing parameters for application-based authentication. If provided, this will be used for connecting to services.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: CISAuthenticationParameters
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -WhatIf
|
||||||
|
Shows what would happen if the cmdlet runs.
|
||||||
|
The cmdlet is not run.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: wi
|
||||||
|
|
||||||
Required: False
|
Required: False
|
||||||
Position: Named
|
Position: Named
|
||||||
Default value: None
|
Default value: None
|
||||||
@@ -410,14 +448,13 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
### -WhatIf
|
### -ProgressAction
|
||||||
Shows what would happen if the cmdlet runs.
|
{{ Fill ProgressAction Description }}
|
||||||
The cmdlet is not run.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
Type: SwitchParameter
|
Type: ActionPreference
|
||||||
Parameter Sets: (All)
|
Parameter Sets: (All)
|
||||||
Aliases: wi
|
Aliases: proga
|
||||||
|
|
||||||
Required: False
|
Required: False
|
||||||
Position: Named
|
Position: Named
|
||||||
|
@@ -26,6 +26,9 @@ Grants Microsoft Graph permissions for an auditor.
|
|||||||
### [Invoke-M365SecurityAudit](Invoke-M365SecurityAudit)
|
### [Invoke-M365SecurityAudit](Invoke-M365SecurityAudit)
|
||||||
Invokes a security audit for Microsoft 365 environments.
|
Invokes a security audit for Microsoft 365 environments.
|
||||||
|
|
||||||
|
### [New-M365SecurityAuditAuthObject](New-M365SecurityAuditAuthObject)
|
||||||
|
Creates a new CISAuthenticationParameters object for Microsoft 365 authentication.
|
||||||
|
|
||||||
### [Remove-RowsWithEmptyCSVStatus](Remove-RowsWithEmptyCSVStatus)
|
### [Remove-RowsWithEmptyCSVStatus](Remove-RowsWithEmptyCSVStatus)
|
||||||
Removes rows from an Excel worksheet where the 'CSV_Status' column is empty and saves the result to a new file.
|
Removes rows from an Excel worksheet where the 'CSV_Status' column is empty and saves the result to a new file.
|
||||||
|
|
||||||
|
149
help/New-M365SecurityAuditAuthObject.md
Normal file
149
help/New-M365SecurityAuditAuthObject.md
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
---
|
||||||
|
external help file: M365FoundationsCISReport-help.xml
|
||||||
|
Module Name: M365FoundationsCISReport
|
||||||
|
online version:
|
||||||
|
schema: 2.0.0
|
||||||
|
---
|
||||||
|
|
||||||
|
# New-M365SecurityAuditAuthObject
|
||||||
|
|
||||||
|
## SYNOPSIS
|
||||||
|
Creates a new CISAuthenticationParameters object for Microsoft 365 authentication.
|
||||||
|
|
||||||
|
## SYNTAX
|
||||||
|
|
||||||
|
```
|
||||||
|
New-M365SecurityAuditAuthObject [-ClientCertThumbPrint] <String> [-ClientId] <String> [-TenantId] <String>
|
||||||
|
[-OnMicrosoftUrl] <String> [-SpAdminUrl] <String> [-ProgressAction <ActionPreference>] [<CommonParameters>]
|
||||||
|
```
|
||||||
|
|
||||||
|
## DESCRIPTION
|
||||||
|
The New-M365SecurityAuditAuthObject function constructs a new CISAuthenticationParameters object
|
||||||
|
containing the necessary credentials and URLs for authenticating to various Microsoft 365 services.
|
||||||
|
It validates input parameters to ensure they conform to expected formats and length requirements.
|
||||||
|
An app registration in Azure AD with the required permissions to EXO, SPO, MSTeams and MgGraph is needed.
|
||||||
|
|
||||||
|
## EXAMPLES
|
||||||
|
|
||||||
|
### EXAMPLE 1
|
||||||
|
```
|
||||||
|
$authParams = New-M365SecurityAuditAuthObject -ClientCertThumbPrint "ABCDEF1234567890ABCDEF1234567890ABCDEF12" `
|
||||||
|
-ClientId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-TenantId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-OnMicrosoftUrl "yourcompany.onmicrosoft.com" `
|
||||||
|
-SpAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
|
Creates a new CISAuthenticationParameters object with the specified credentials and URLs, validating each parameter's format and length.
|
||||||
|
```
|
||||||
|
|
||||||
|
## PARAMETERS
|
||||||
|
|
||||||
|
### -ClientCertThumbPrint
|
||||||
|
The thumbprint of the client certificate used for authentication.
|
||||||
|
It must be a 40-character hexadecimal string.
|
||||||
|
This certificate is used to authenticate the application in Azure AD.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: 1
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -ClientId
|
||||||
|
The Client ID (Application ID) of the Azure AD application.
|
||||||
|
It must be a valid GUID format.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: 2
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -TenantId
|
||||||
|
The Tenant ID of the Azure AD directory.
|
||||||
|
It must be a valid GUID format representing your Microsoft 365 tenant.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: 3
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -OnMicrosoftUrl
|
||||||
|
The URL of your onmicrosoft.com domain.
|
||||||
|
It should be in the format 'example.onmicrosoft.com'.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: 4
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -SpAdminUrl
|
||||||
|
The SharePoint admin URL, which should end with '-admin.sharepoint.com'.
|
||||||
|
This URL is used for connecting to SharePoint Online.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: 5
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -ProgressAction
|
||||||
|
{{ Fill ProgressAction Description }}
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: ActionPreference
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: proga
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### CommonParameters
|
||||||
|
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||||
|
|
||||||
|
## INPUTS
|
||||||
|
|
||||||
|
### None. You cannot pipe objects to this function.
|
||||||
|
## OUTPUTS
|
||||||
|
|
||||||
|
### CISAuthenticationParameters
|
||||||
|
### The function returns an instance of the CISAuthenticationParameters class containing the authentication details.
|
||||||
|
## NOTES
|
||||||
|
Requires PowerShell 7.0 or later.
|
||||||
|
|
||||||
|
## RELATED LINKS
|
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
external help file: M365FoundationsCISReport-help.xml
|
external help file: M365FoundationsCISReport-help.xml
|
||||||
Module Name: M365FoundationsCISReport
|
Module Name: M365FoundationsCISReport
|
||||||
online version:
|
online version:
|
||||||
@@ -13,7 +13,8 @@ Removes rows from an Excel worksheet where the 'CSV_Status' column is empty and
|
|||||||
## SYNTAX
|
## SYNTAX
|
||||||
|
|
||||||
```
|
```
|
||||||
Remove-RowsWithEmptyCSVStatus [-FilePath] <String> [-WorksheetName] <String> [<CommonParameters>]
|
Remove-RowsWithEmptyCSVStatus [-FilePath] <String> [-WorksheetName] <String>
|
||||||
|
[-ProgressAction <ActionPreference>] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
@@ -60,6 +61,21 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### -ProgressAction
|
||||||
|
{{ Fill ProgressAction Description }}
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: ActionPreference
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: proga
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
### CommonParameters
|
### CommonParameters
|
||||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
external help file: M365FoundationsCISReport-help.xml
|
external help file: M365FoundationsCISReport-help.xml
|
||||||
Module Name: M365FoundationsCISReport
|
Module Name: M365FoundationsCISReport
|
||||||
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Sync-CISExcelAndCsvData
|
online version: https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Sync-CISExcelAndCsvData
|
||||||
@@ -14,7 +14,7 @@ Synchronizes and updates data in an Excel worksheet with new information from a
|
|||||||
|
|
||||||
```
|
```
|
||||||
Sync-CISExcelAndCsvData [[-ExcelPath] <String>] [[-CsvPath] <String>] [[-SheetName] <String>]
|
Sync-CISExcelAndCsvData [[-ExcelPath] <String>] [[-CsvPath] <String>] [[-SheetName] <String>]
|
||||||
[<CommonParameters>]
|
[-ProgressAction <ActionPreference>] [<CommonParameters>]
|
||||||
```
|
```
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
@@ -32,22 +32,6 @@ Updates the 'AuditData' worksheet in 'excel.xlsx' with data from 'data.csv', add
|
|||||||
|
|
||||||
## PARAMETERS
|
## PARAMETERS
|
||||||
|
|
||||||
### -CsvPath
|
|
||||||
Specifies the path to the CSV file containing new data.
|
|
||||||
This parameter is mandatory.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
Type: String
|
|
||||||
Parameter Sets: (All)
|
|
||||||
Aliases:
|
|
||||||
|
|
||||||
Required: False
|
|
||||||
Position: 2
|
|
||||||
Default value: None
|
|
||||||
Accept pipeline input: False
|
|
||||||
Accept wildcard characters: False
|
|
||||||
```
|
|
||||||
|
|
||||||
### -ExcelPath
|
### -ExcelPath
|
||||||
Specifies the path to the Excel file to be updated.
|
Specifies the path to the Excel file to be updated.
|
||||||
This parameter is mandatory.
|
This parameter is mandatory.
|
||||||
@@ -64,6 +48,22 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### -CsvPath
|
||||||
|
Specifies the path to the CSV file containing new data.
|
||||||
|
This parameter is mandatory.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: 2
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
### -SheetName
|
### -SheetName
|
||||||
Specifies the name of the worksheet in the Excel file where data will be merged and updated.
|
Specifies the name of the worksheet in the Excel file where data will be merged and updated.
|
||||||
This parameter is mandatory.
|
This parameter is mandatory.
|
||||||
@@ -80,6 +80,21 @@ Accept pipeline input: False
|
|||||||
Accept wildcard characters: False
|
Accept wildcard characters: False
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### -ProgressAction
|
||||||
|
{{ Fill ProgressAction Description }}
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: ActionPreference
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: proga
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
### CommonParameters
|
### CommonParameters
|
||||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||||
|
|
||||||
|
@@ -38,6 +38,14 @@ Sync-CISExcelAndCsvData -ExcelPath "path\to\excel.xlsx" -CsvPath "path\to\data.c
|
|||||||
|
|
||||||
# Example 7: Granting Microsoft Graph permissions to the auditor
|
# Example 7: Granting Microsoft Graph permissions to the auditor
|
||||||
Grant-M365SecurityAuditConsent -UserPrincipalNameForConsent 'user@example.com'
|
Grant-M365SecurityAuditConsent -UserPrincipalNameForConsent 'user@example.com'
|
||||||
|
|
||||||
|
# Example 8: (PowerShell 7.x Only) Creating a new authentication object for the security audit for app-based authentication.
|
||||||
|
$authParams = New-M365SecurityAuditAuthObject -ClientCertThumbPrint "ABCDEF1234567890ABCDEF1234567890ABCDEF12" `
|
||||||
|
-ClientId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-TenantId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-OnMicrosoftUrl "yourcompany.onmicrosoft.com" `
|
||||||
|
-SpAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
|
Invoke-M365SecurityAudit -AuthParams $authParams -TenantAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
```
|
```
|
||||||
|
|
||||||
# NOTE
|
# NOTE
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
Import-Module .\output\module\M365FoundationsCISReport\*\*.psd1
|
Import-Module .\output\module\M365FoundationsCISReport\*\*.psd1
|
||||||
. .\source\Classes\CISAuditResult.ps1
|
. .\source\Classes\CISAuditResult.ps1
|
||||||
.\helpers\psDoc-master\src\psDoc.ps1 -moduleName M365FoundationsCISReport -outputDir docs -template ".\helpers\psDoc-master\src\out-html-template.ps1"
|
.\helpers\psDoc-master\src\psDoc.ps1 -moduleName M365FoundationsCISReport -outputDir docs -template ".\helpers\psDoc-master\src\out-html-template.ps1"
|
||||||
.\helpers\psDoc-master\src\psDoc.ps1 -moduleName M365FoundationsCISReport -outputDir ".\" -template ".\helpers\psDoc-master\src\out-markdown-template.ps1" -fileName ".\README.md" -
|
.\helpers\psDoc-master\src\psDoc.ps1 -moduleName M365FoundationsCISReport -outputDir ".\" -template ".\helpers\psDoc-master\src\out-markdown-template.ps1" -fileName ".\README.md"
|
||||||
|
|
||||||
|
|
||||||
<#
|
<#
|
||||||
$ver = "v0.1.24"
|
$ver = "v0.1.28"
|
||||||
git checkout main
|
git checkout main
|
||||||
git pull origin main
|
git pull origin main
|
||||||
git tag -a $ver -m "Release version $ver refactor Update"
|
git tag -a $ver -m "Release version $ver bugfix Update"
|
||||||
git push origin $ver
|
git push origin $ver
|
||||||
"Fix: PR #37"
|
"Fix: PR #37"
|
||||||
git push origin $ver
|
git push origin $ver
|
||||||
@@ -53,8 +53,8 @@ Register-SecretVault -Name ModuleBuildCreds -ModuleName `
|
|||||||
"SecretManagement.JustinGrote.CredMan" -ErrorAction Stop
|
"SecretManagement.JustinGrote.CredMan" -ErrorAction Stop
|
||||||
|
|
||||||
|
|
||||||
Set-Secret -Name "GalleryApiToken" -Vault ModuleBuildCreds
|
#Set-Secret -Name "GalleryApiToken" -Vault ModuleBuildCreds
|
||||||
Set-Secret -Name "GitHubToken" -Vault ModuleBuildCreds
|
#Set-Secret -Name "GitHubToken" -Vault ModuleBuildCreds
|
||||||
|
|
||||||
|
|
||||||
$GalleryApiToken = Get-Secret -Name "GalleryApiToken" -Vault ModuleBuildCreds -AsPlainText
|
$GalleryApiToken = Get-Secret -Name "GalleryApiToken" -Vault ModuleBuildCreds -AsPlainText
|
||||||
|
43
source/Classes/CISAuthenticationParameters.ps1
Normal file
43
source/Classes/CISAuthenticationParameters.ps1
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
class CISAuthenticationParameters {
|
||||||
|
[string]$ClientCertThumbPrint
|
||||||
|
[string]$ClientId
|
||||||
|
[string]$TenantId
|
||||||
|
[string]$OnMicrosoftUrl
|
||||||
|
[string]$SpAdminUrl
|
||||||
|
|
||||||
|
# Constructor with validation
|
||||||
|
CISAuthenticationParameters(
|
||||||
|
[string]$ClientCertThumbPrint,
|
||||||
|
[string]$ClientId,
|
||||||
|
[string]$TenantId,
|
||||||
|
[string]$OnMicrosoftUrl,
|
||||||
|
[string]$SpAdminUrl
|
||||||
|
) {
|
||||||
|
# Validate ClientCertThumbPrint
|
||||||
|
if (-not $ClientCertThumbPrint -or $ClientCertThumbPrint.Length -ne 40 -or $ClientCertThumbPrint -notmatch '^[0-9a-fA-F]{40}$') {
|
||||||
|
throw [ArgumentException]::new("ClientCertThumbPrint must be a 40-character hexadecimal string.")
|
||||||
|
}
|
||||||
|
# Validate ClientId
|
||||||
|
if (-not $ClientId -or $ClientId -notmatch '^[0-9a-fA-F\-]{36}$') {
|
||||||
|
throw [ArgumentException]::new("ClientId must be a valid GUID in the format 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'.")
|
||||||
|
}
|
||||||
|
# Validate TenantId
|
||||||
|
if (-not $TenantId -or $TenantId -notmatch '^[0-9a-fA-F\-]{36}$') {
|
||||||
|
throw [ArgumentException]::new("TenantId must be a valid GUID in the format 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'.")
|
||||||
|
}
|
||||||
|
# Validate OnMicrosoftUrl
|
||||||
|
if (-not $OnMicrosoftUrl -or $OnMicrosoftUrl -notmatch '^[a-zA-Z0-9]+\.onmicrosoft\.com$') {
|
||||||
|
throw [ArgumentException]::new("OnMicrosoftUrl must be in the format 'example.onmicrosoft.com'.")
|
||||||
|
}
|
||||||
|
# Validate SpAdminUrl
|
||||||
|
if (-not $SpAdminUrl -or $SpAdminUrl -notmatch '^https:\/\/[a-zA-Z0-9\-]+\-admin\.sharepoint\.com$') {
|
||||||
|
throw [ArgumentException]::new("SpAdminUrl must be in the format 'https://[name]-admin.sharepoint.com'.")
|
||||||
|
}
|
||||||
|
# Assign validated properties
|
||||||
|
$this.ClientCertThumbPrint = $ClientCertThumbPrint
|
||||||
|
$this.ClientId = $ClientId
|
||||||
|
$this.TenantId = $TenantId
|
||||||
|
$this.OnMicrosoftUrl = $OnMicrosoftUrl
|
||||||
|
$this.SpAdminUrl = $SpAdminUrl
|
||||||
|
}
|
||||||
|
}
|
@@ -33,7 +33,7 @@ Copyright = '(c) 2024 Douglas S. Rios (DrIOSx). All rights reserved.'
|
|||||||
Description = 'Automated assessment of 50 CIS 365 Foundations v3.0.0 benchmark.'
|
Description = 'Automated assessment of 50 CIS 365 Foundations v3.0.0 benchmark.'
|
||||||
|
|
||||||
# Minimum version of the Windows PowerShell engine required by this module
|
# Minimum version of the Windows PowerShell engine required by this module
|
||||||
PowerShellVersion = '5.0'
|
# PowerShellVersion = '5.1'
|
||||||
|
|
||||||
# Name of the Windows PowerShell host required by this module
|
# Name of the Windows PowerShell host required by this module
|
||||||
# PowerShellHostName = ''
|
# PowerShellHostName = ''
|
||||||
@@ -51,7 +51,7 @@ PowerShellVersion = '5.0'
|
|||||||
# ProcessorArchitecture = ''
|
# ProcessorArchitecture = ''
|
||||||
|
|
||||||
# Modules that must be imported into the global environment prior to importing this module
|
# Modules that must be imported into the global environment prior to importing this module
|
||||||
RequiredModules = @()
|
# RequiredModules = @()
|
||||||
|
|
||||||
# Assemblies that must be loaded prior to importing this module
|
# Assemblies that must be loaded prior to importing this module
|
||||||
# RequiredAssemblies = @()
|
# RequiredAssemblies = @()
|
||||||
|
@@ -1,37 +1,49 @@
|
|||||||
function Assert-ModuleAvailability {
|
function Assert-ModuleAvailability {
|
||||||
|
[CmdletBinding()]
|
||||||
[OutputType([void]) ]
|
[OutputType([void]) ]
|
||||||
param(
|
param(
|
||||||
[string]$ModuleName,
|
[string]$ModuleName,
|
||||||
[string]$RequiredVersion,
|
[string]$RequiredVersion,
|
||||||
[string[]]$SubModules = @()
|
[string[]]$SubModules = @()
|
||||||
)
|
)
|
||||||
|
process {
|
||||||
try {
|
try {
|
||||||
$module = Get-Module -ListAvailable -Name $ModuleName | Where-Object { $_.Version -ge [version]$RequiredVersion }
|
$module = Get-Module -ListAvailable -Name $ModuleName | Where-Object { $_.Version -ge [version]$RequiredVersion }
|
||||||
|
|
||||||
if ($null -eq $module) {
|
if ($null -eq $module) {
|
||||||
Write-Host "Installing $ModuleName module..." -ForegroundColor Yellow
|
Write-Verbose "Installing $ModuleName module..."
|
||||||
Install-Module -Name $ModuleName -RequiredVersion $RequiredVersion -Force -AllowClobber -Scope CurrentUser | Out-Null
|
Install-Module -Name $ModuleName -RequiredVersion $RequiredVersion -Force -AllowClobber -Scope CurrentUser | Out-Null
|
||||||
}
|
}
|
||||||
elseif ($module.Version -lt [version]$RequiredVersion) {
|
elseif ($module.Version -lt [version]$RequiredVersion) {
|
||||||
Write-Host "Updating $ModuleName module to required version..." -ForegroundColor Yellow
|
Write-Verbose "Updating $ModuleName module to required version..."
|
||||||
Update-Module -Name $ModuleName -RequiredVersion $RequiredVersion -Force | Out-Null
|
Update-Module -Name $ModuleName -RequiredVersion $RequiredVersion -Force | Out-Null
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Host "$ModuleName module is already at required version or newer." -ForegroundColor Gray
|
Write-Verbose "$ModuleName module is already at required version or newer."
|
||||||
|
}
|
||||||
|
if ($ModuleName -eq "Microsoft.Graph") {
|
||||||
|
# "Preloading Microsoft.Graph assembly to prevent type-loading issues..."
|
||||||
|
Write-Verbose "Preloading Microsoft.Graph assembly to prevent type-loading issues..."
|
||||||
|
try {
|
||||||
|
# Run a harmless cmdlet to preload the assembly
|
||||||
|
Get-MgGroup -Top 1 -ErrorAction SilentlyContinue | Out-Null
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Verbose "Could not preload Microsoft.Graph assembly. Error: $_"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($SubModules.Count -gt 0) {
|
if ($SubModules.Count -gt 0) {
|
||||||
foreach ($subModule in $SubModules) {
|
foreach ($subModule in $SubModules) {
|
||||||
Write-Host "Importing submodule $ModuleName.$subModule..." -ForegroundColor DarkGray
|
Write-Verbose "Importing submodule $ModuleName.$subModule..."
|
||||||
Import-Module -Name "$ModuleName.$subModule" -RequiredVersion $RequiredVersion -ErrorAction Stop | Out-Null
|
Get-Module "$ModuleName.$subModule" | Import-Module -RequiredVersion $RequiredVersion -ErrorAction Stop | Out-Null
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
Write-Host "Importing module $ModuleName..." -ForegroundColor DarkGray
|
else {
|
||||||
|
Write-Verbose "Importing module $ModuleName..."
|
||||||
Import-Module -Name $ModuleName -RequiredVersion $RequiredVersion -ErrorAction Stop -WarningAction SilentlyContinue | Out-Null
|
Import-Module -Name $ModuleName -RequiredVersion $RequiredVersion -ErrorAction Stop -WarningAction SilentlyContinue | Out-Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Warning "An error occurred with module $ModuleName`: $_"
|
throw "Assert-ModuleAvailability:`n$_"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -5,6 +5,9 @@ function Connect-M365Suite {
|
|||||||
[Parameter(Mandatory = $false)]
|
[Parameter(Mandatory = $false)]
|
||||||
[string]$TenantAdminUrl,
|
[string]$TenantAdminUrl,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[CISAuthenticationParameters]$AuthParams,
|
||||||
|
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
[string[]]$RequiredConnections,
|
[string[]]$RequiredConnections,
|
||||||
|
|
||||||
@@ -12,111 +15,131 @@ function Connect-M365Suite {
|
|||||||
[switch]$SkipConfirmation
|
[switch]$SkipConfirmation
|
||||||
)
|
)
|
||||||
|
|
||||||
$VerbosePreference = "SilentlyContinue"
|
$VerbosePreference = if ($SkipConfirmation) { 'SilentlyContinue' } else { 'Continue' }
|
||||||
$tenantInfo = @()
|
$tenantInfo = @()
|
||||||
$connectedServices = @()
|
$connectedServices = @()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($RequiredConnections -contains "AzureAD" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "AzureAD | EXO | Microsoft Graph") {
|
if ($RequiredConnections -contains 'Microsoft Graph' -or $RequiredConnections -contains 'EXO | Microsoft Graph') {
|
||||||
Write-Host "Connecting to Azure Active Directory..." -ForegroundColor Yellow
|
|
||||||
Connect-AzureAD -WarningAction SilentlyContinue | Out-Null
|
|
||||||
$tenantDetails = Get-AzureADTenantDetail -WarningAction SilentlyContinue
|
|
||||||
$tenantInfo += [PSCustomObject]@{
|
|
||||||
Service = "Azure Active Directory"
|
|
||||||
TenantName = $tenantDetails.DisplayName
|
|
||||||
TenantID = $tenantDetails.ObjectId
|
|
||||||
}
|
|
||||||
$connectedServices += "AzureAD"
|
|
||||||
Write-Host "Successfully connected to Azure Active Directory." -ForegroundColor Green
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($RequiredConnections -contains "Microsoft Graph" -or $RequiredConnections -contains "EXO | Microsoft Graph") {
|
|
||||||
Write-Host "Connecting to Microsoft Graph with scopes: Directory.Read.All, Domain.Read.All, Policy.Read.All, Organization.Read.All" -ForegroundColor Yellow
|
|
||||||
try {
|
try {
|
||||||
Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -NoWelcome | Out-Null
|
Write-Verbose 'Connecting to Microsoft Graph...'
|
||||||
|
if ($AuthParams) {
|
||||||
|
Connect-MgGraph -CertificateThumbprint $AuthParams.ClientCertThumbPrint -AppId $AuthParams.ClientId -TenantId $AuthParams.TenantId -NoWelcome | Out-Null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Connect-MgGraph -Scopes 'Directory.Read.All', 'Domain.Read.All', 'Policy.Read.All', 'Organization.Read.All' -NoWelcome | Out-Null
|
||||||
|
}
|
||||||
$graphOrgDetails = Get-MgOrganization
|
$graphOrgDetails = Get-MgOrganization
|
||||||
$tenantInfo += [PSCustomObject]@{
|
$tenantInfo += [PSCustomObject]@{
|
||||||
Service = "Microsoft Graph"
|
Service = 'Microsoft Graph'
|
||||||
TenantName = $graphOrgDetails.DisplayName
|
TenantName = $graphOrgDetails.DisplayName
|
||||||
TenantID = $graphOrgDetails.Id
|
TenantID = $graphOrgDetails.Id
|
||||||
}
|
}
|
||||||
$connectedServices += "Microsoft Graph"
|
$connectedServices += 'Microsoft Graph'
|
||||||
Write-Host "Successfully connected to Microsoft Graph with specified scopes." -ForegroundColor Green
|
Write-Verbose 'Successfully connected to Microsoft Graph.'
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Host "Failed to connect to MgGraph, attempting device auth." -ForegroundColor Yellow
|
throw "Failed to connect to Microsoft Graph: $($_.Exception.Message)"
|
||||||
Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -UseDeviceCode -NoWelcome | Out-Null
|
|
||||||
$graphOrgDetails = Get-MgOrganization
|
|
||||||
$tenantInfo += [PSCustomObject]@{
|
|
||||||
Service = "Microsoft Graph"
|
|
||||||
TenantName = $graphOrgDetails.DisplayName
|
|
||||||
TenantID = $graphOrgDetails.Id
|
|
||||||
}
|
|
||||||
$connectedServices += "Microsoft Graph"
|
|
||||||
Write-Host "Successfully connected to Microsoft Graph with specified scopes." -ForegroundColor Green
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($RequiredConnections -contains "EXO" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "Microsoft Teams | EXO" -or $RequiredConnections -contains "EXO | Microsoft Graph") {
|
if ($RequiredConnections -contains 'EXO' -or $RequiredConnections -contains 'AzureAD | EXO' -or $RequiredConnections -contains 'Microsoft Teams | EXO' -or $RequiredConnections -contains 'EXO | Microsoft Graph') {
|
||||||
Write-Host "Connecting to Exchange Online..." -ForegroundColor Yellow
|
try {
|
||||||
|
Write-Verbose 'Connecting to Exchange Online...'
|
||||||
|
if ($AuthParams) {
|
||||||
|
Connect-ExchangeOnline -AppId $AuthParams.ClientId -CertificateThumbprint $AuthParams.ClientCertThumbPrint -Organization $AuthParams.OnMicrosoftUrl -ShowBanner:$false | Out-Null
|
||||||
|
}
|
||||||
|
else {
|
||||||
Connect-ExchangeOnline -ShowBanner:$false | Out-Null
|
Connect-ExchangeOnline -ShowBanner:$false | Out-Null
|
||||||
|
}
|
||||||
$exoTenant = (Get-OrganizationConfig).Identity
|
$exoTenant = (Get-OrganizationConfig).Identity
|
||||||
$tenantInfo += [PSCustomObject]@{
|
$tenantInfo += [PSCustomObject]@{
|
||||||
Service = "Exchange Online"
|
Service = 'Exchange Online'
|
||||||
TenantName = $exoTenant
|
TenantName = $exoTenant
|
||||||
TenantID = "N/A"
|
TenantID = 'N/A'
|
||||||
|
}
|
||||||
|
$connectedServices += 'EXO'
|
||||||
|
Write-Verbose 'Successfully connected to Exchange Online.'
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw "Failed to connect to Exchange Online: $($_.Exception.Message)"
|
||||||
}
|
}
|
||||||
$connectedServices += "EXO"
|
|
||||||
Write-Host "Successfully connected to Exchange Online." -ForegroundColor Green
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($RequiredConnections -contains "SPO") {
|
if ($RequiredConnections -contains 'SPO') {
|
||||||
Write-Host "Connecting to SharePoint Online..." -ForegroundColor Yellow
|
try {
|
||||||
|
Write-Verbose 'Connecting to SharePoint Online...'
|
||||||
|
if ($AuthParams) {
|
||||||
|
Connect-PnPOnline -Url $AuthParams.SpAdminUrl -ClientId $AuthParams.ClientId -Tenant $AuthParams.OnMicrosoftUrl -Thumbprint $AuthParams.ClientCertThumbPrint | Out-Null
|
||||||
|
}
|
||||||
|
else {
|
||||||
Connect-SPOService -Url $TenantAdminUrl | Out-Null
|
Connect-SPOService -Url $TenantAdminUrl | Out-Null
|
||||||
$spoContext = Get-SPOCrossTenantHostUrl
|
}
|
||||||
$tenantName = Get-UrlLine -Output $spoContext
|
$tenantName = if ($AuthParams) {
|
||||||
|
(Get-PnPSite).Url
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Supress output from Get-SPOSite for powerautomate to avoid errors
|
||||||
|
[void]($sites = Get-SPOSite -Limit All)
|
||||||
|
# Get the URL from the first site collection
|
||||||
|
$url = $sites[0].Url
|
||||||
|
# Use regex to extract the base URL up to the .com portion
|
||||||
|
$baseUrl = [regex]::Match($url, 'https://[^/]+.com').Value
|
||||||
|
# Output the base URL
|
||||||
|
$baseUrl
|
||||||
|
}
|
||||||
$tenantInfo += [PSCustomObject]@{
|
$tenantInfo += [PSCustomObject]@{
|
||||||
Service = "SharePoint Online"
|
Service = 'SharePoint Online'
|
||||||
TenantName = $tenantName
|
TenantName = $tenantName
|
||||||
}
|
}
|
||||||
$connectedServices += "SPO"
|
$connectedServices += 'SPO'
|
||||||
Write-Host "Successfully connected to SharePoint Online." -ForegroundColor Green
|
Write-Verbose 'Successfully connected to SharePoint Online.'
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw "Failed to connect to SharePoint Online: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($RequiredConnections -contains "Microsoft Teams" -or $RequiredConnections -contains "Microsoft Teams | EXO") {
|
if ($RequiredConnections -contains 'Microsoft Teams' -or $RequiredConnections -contains 'Microsoft Teams | EXO') {
|
||||||
Write-Host "Connecting to Microsoft Teams..." -ForegroundColor Yellow
|
try {
|
||||||
|
Write-Verbose 'Connecting to Microsoft Teams...'
|
||||||
|
if ($AuthParams) {
|
||||||
|
Connect-MicrosoftTeams -TenantId $AuthParams.TenantId -CertificateThumbprint $AuthParams.ClientCertThumbPrint -ApplicationId $AuthParams.ClientId | Out-Null
|
||||||
|
}
|
||||||
|
else {
|
||||||
Connect-MicrosoftTeams | Out-Null
|
Connect-MicrosoftTeams | Out-Null
|
||||||
|
}
|
||||||
$teamsTenantDetails = Get-CsTenant
|
$teamsTenantDetails = Get-CsTenant
|
||||||
$tenantInfo += [PSCustomObject]@{
|
$tenantInfo += [PSCustomObject]@{
|
||||||
Service = "Microsoft Teams"
|
Service = 'Microsoft Teams'
|
||||||
TenantName = $teamsTenantDetails.DisplayName
|
TenantName = $teamsTenantDetails.DisplayName
|
||||||
TenantID = $teamsTenantDetails.TenantId
|
TenantID = $teamsTenantDetails.TenantId
|
||||||
}
|
}
|
||||||
$connectedServices += "Microsoft Teams"
|
$connectedServices += 'Microsoft Teams'
|
||||||
Write-Host "Successfully connected to Microsoft Teams." -ForegroundColor Green
|
Write-Verbose 'Successfully connected to Microsoft Teams.'
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw "Failed to connect to Microsoft Teams: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Display tenant information and confirm with the user
|
|
||||||
if (-not $SkipConfirmation) {
|
if (-not $SkipConfirmation) {
|
||||||
Write-Host "Connected to the following tenants:" -ForegroundColor Yellow
|
Write-Verbose 'Connected to the following tenants:'
|
||||||
foreach ($tenant in $tenantInfo) {
|
foreach ($tenant in $tenantInfo) {
|
||||||
Write-Host "Service: $($tenant.Service)" -ForegroundColor Cyan
|
Write-Verbose "Service: $($tenant.Service) | Tenant: $($tenant.TenantName)"
|
||||||
Write-Host "Tenant Context: $($tenant.TenantName)`n" -ForegroundColor Green
|
|
||||||
#Write-Host "Tenant ID: $($tenant.TenantID)"
|
|
||||||
}
|
}
|
||||||
$confirmation = Read-Host "Do you want to proceed with these connections? (Y/N)"
|
$confirmation = Read-Host 'Do you want to proceed with these connections? (Y/N)'
|
||||||
if ($confirmation -notlike 'Y') {
|
if ($confirmation -notlike 'Y') {
|
||||||
Write-Host "Connection setup aborted by user." -ForegroundColor Red
|
|
||||||
Disconnect-M365Suite -RequiredConnections $connectedServices
|
Disconnect-M365Suite -RequiredConnections $connectedServices
|
||||||
throw "User aborted connection setup."
|
throw 'User aborted connection setup.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
$VerbosePreference = "Continue"
|
$VerbosePreference = 'Continue'
|
||||||
Write-Host "There was an error establishing one or more connections: $_" -ForegroundColor Red
|
throw "Connection failed: $($_.Exception.Message)"
|
||||||
throw $_
|
}
|
||||||
|
finally {
|
||||||
|
$VerbosePreference = 'Continue'
|
||||||
}
|
}
|
||||||
|
|
||||||
$VerbosePreference = "Continue"
|
|
||||||
}
|
}
|
@@ -8,7 +8,7 @@ function Disconnect-M365Suite {
|
|||||||
# Clean up sessions
|
# Clean up sessions
|
||||||
try {
|
try {
|
||||||
if ($RequiredConnections -contains "EXO" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "Microsoft Teams | EXO") {
|
if ($RequiredConnections -contains "EXO" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "Microsoft Teams | EXO") {
|
||||||
Write-Host "Disconnecting from Exchange Online..." -ForegroundColor Green
|
Write-Verbose "Disconnecting from Exchange Online..."
|
||||||
Disconnect-ExchangeOnline -Confirm:$false | Out-Null
|
Disconnect-ExchangeOnline -Confirm:$false | Out-Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ function Disconnect-M365Suite {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if ($RequiredConnections -contains "AzureAD" -or $RequiredConnections -contains "AzureAD | EXO") {
|
if ($RequiredConnections -contains "AzureAD" -or $RequiredConnections -contains "AzureAD | EXO") {
|
||||||
Write-Host "Disconnecting from Azure AD..." -ForegroundColor Green
|
Write-Verbose "Disconnecting from Azure AD..."
|
||||||
Disconnect-AzureAD | Out-Null
|
Disconnect-AzureAD | Out-Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ function Disconnect-M365Suite {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if ($RequiredConnections -contains "Microsoft Graph") {
|
if ($RequiredConnections -contains "Microsoft Graph") {
|
||||||
Write-Host "Disconnecting from Microsoft Graph..." -ForegroundColor Green
|
Write-Verbose "Disconnecting from Microsoft Graph..."
|
||||||
Disconnect-MgGraph | Out-Null
|
Disconnect-MgGraph | Out-Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,23 +38,28 @@ function Disconnect-M365Suite {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if ($RequiredConnections -contains "SPO") {
|
if ($RequiredConnections -contains "SPO") {
|
||||||
Write-Host "Disconnecting from SharePoint Online..." -ForegroundColor Green
|
if (($script:PnpAuth)) {
|
||||||
|
Write-Verbose "Disconnecting from PnPOnline..."
|
||||||
|
Disconnect-PnPOnline | Out-Null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Verbose "Disconnecting from SharePoint Online..."
|
||||||
Disconnect-SPOService | Out-Null
|
Disconnect-SPOService | Out-Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Warning "Failed to disconnect from SharePoint Online: $_"
|
Write-Warning "Failed to disconnect from SharePoint Online: $_"
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($RequiredConnections -contains "Microsoft Teams" -or $RequiredConnections -contains "Microsoft Teams | EXO") {
|
if ($RequiredConnections -contains "Microsoft Teams" -or $RequiredConnections -contains "Microsoft Teams | EXO") {
|
||||||
Write-Host "Disconnecting from Microsoft Teams..." -ForegroundColor Green
|
Write-Verbose "Disconnecting from Microsoft Teams..."
|
||||||
Disconnect-MicrosoftTeams | Out-Null
|
Disconnect-MicrosoftTeams | Out-Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Warning "Failed to disconnect from Microsoft Teams: $_"
|
Write-Warning "Failed to disconnect from Microsoft Teams: $_"
|
||||||
}
|
}
|
||||||
|
Write-Verbose "All necessary sessions have been disconnected."
|
||||||
Write-Host "All necessary sessions have been disconnected." -ForegroundColor Green
|
|
||||||
}
|
}
|
@@ -46,6 +46,7 @@ function Get-CISExoOutput {
|
|||||||
#>
|
#>
|
||||||
}
|
}
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
Write-Verbose "Get-CISExoOutput: Retuning data for Rec: $Rec"
|
Write-Verbose "Get-CISExoOutput: Retuning data for Rec: $Rec"
|
||||||
switch ($Rec) {
|
switch ($Rec) {
|
||||||
'1.2.2' {
|
'1.2.2' {
|
||||||
@@ -479,6 +480,10 @@ function Get-CISExoOutput {
|
|||||||
default { throw "No match found for test: $Rec" }
|
default { throw "No match found for test: $Rec" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
throw "Get-CISExoOutput: `n$_"
|
||||||
|
}
|
||||||
|
}
|
||||||
end {
|
end {
|
||||||
Write-Verbose "Retuning data for Rec: $Rec"
|
Write-Verbose "Retuning data for Rec: $Rec"
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ function Get-CISMSTeamsOutput {
|
|||||||
#>
|
#>
|
||||||
}
|
}
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
Write-Verbose "Get-CISMSTeamsOutput: Retuning data for Rec: $Rec"
|
Write-Verbose "Get-CISMSTeamsOutput: Retuning data for Rec: $Rec"
|
||||||
switch ($Rec) {
|
switch ($Rec) {
|
||||||
'8.1.1' {
|
'8.1.1' {
|
||||||
@@ -326,6 +327,10 @@ function Get-CISMSTeamsOutput {
|
|||||||
default { throw "No match found for test: $Rec" }
|
default { throw "No match found for test: $Rec" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
throw "Get-CISMSTeamsOutput: `n$_"
|
||||||
|
}
|
||||||
|
}
|
||||||
end {
|
end {
|
||||||
Write-Verbose "Retuning data for Rec: $Rec"
|
Write-Verbose "Retuning data for Rec: $Rec"
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,7 @@ function Get-CISMgOutput {
|
|||||||
#>
|
#>
|
||||||
}
|
}
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
Write-Verbose "Get-CISMgOutput: Retuning data for Rec: $Rec"
|
Write-Verbose "Get-CISMgOutput: Retuning data for Rec: $Rec"
|
||||||
switch ($rec) {
|
switch ($rec) {
|
||||||
'1.1.1' {
|
'1.1.1' {
|
||||||
@@ -59,6 +60,11 @@ function Get-CISMgOutput {
|
|||||||
$allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility
|
$allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility
|
||||||
return $allGroups
|
return $allGroups
|
||||||
}
|
}
|
||||||
|
'1.2.2' {
|
||||||
|
# Test-BlockSharedMailboxSignIn.ps1
|
||||||
|
$users = Get-MgUser
|
||||||
|
return $users
|
||||||
|
}
|
||||||
'1.3.1' {
|
'1.3.1' {
|
||||||
# Test-PasswordNeverExpirePolicy.ps1
|
# Test-PasswordNeverExpirePolicy.ps1
|
||||||
$domains = if ($DomainName) {
|
$domains = if ($DomainName) {
|
||||||
@@ -83,11 +89,11 @@ function Get-CISMgOutput {
|
|||||||
}
|
}
|
||||||
'6.1.2' {
|
'6.1.2' {
|
||||||
# Test-MailboxAuditingE3
|
# Test-MailboxAuditingE3
|
||||||
$tenantSkus = Get-MgSubscribedSku -All
|
$tenantSKUs = Get-MgSubscribedSku -All
|
||||||
$e3SkuPartNumber = "SPE_E3"
|
$e3SkuPartNumber = "SPE_E3"
|
||||||
$founde3Sku = $tenantSkus | Where-Object { $_.SkuPartNumber -eq $e3SkuPartNumber }
|
$foundE3Sku = $tenantSKUs | Where-Object { $_.SkuPartNumber -eq $e3SkuPartNumber }
|
||||||
if ($founde3Sku.Count -ne 0) {
|
if ($foundE3Sku.Count -ne 0) {
|
||||||
$allE3Users = Get-MgUser -Filter "assignedLicenses/any(x:x/skuId eq $($founde3Sku.SkuId) )" -All
|
$allE3Users = Get-MgUser -Filter "assignedLicenses/any(x:x/skuId eq $($foundE3Sku.SkuId) )" -All
|
||||||
return $allE3Users
|
return $allE3Users
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -96,11 +102,11 @@ function Get-CISMgOutput {
|
|||||||
}
|
}
|
||||||
'6.1.3' {
|
'6.1.3' {
|
||||||
# Test-MailboxAuditingE5
|
# Test-MailboxAuditingE5
|
||||||
$tenantSkus = Get-MgSubscribedSku -All
|
$tenantSKUs = Get-MgSubscribedSku -All
|
||||||
$e5SkuPartNumber = "SPE_E5"
|
$e5SkuPartNumber = "SPE_E5"
|
||||||
$founde5Sku = $tenantSkus | Where-Object { $_.SkuPartNumber -eq $e5SkuPartNumber }
|
$foundE5Sku = $tenantSKUs | Where-Object { $_.SkuPartNumber -eq $e5SkuPartNumber }
|
||||||
if ($founde5Sku.Count -ne 0) {
|
if ($foundE5Sku.Count -ne 0) {
|
||||||
$allE5Users = Get-MgUser -Filter "assignedLicenses/any(x:x/skuId eq $($founde5Sku.SkuId) )" -All
|
$allE5Users = Get-MgUser -Filter "assignedLicenses/any(x:x/skuId eq $($foundE5Sku.SkuId) )" -All
|
||||||
return $allE5Users
|
return $allE5Users
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -110,6 +116,10 @@ function Get-CISMgOutput {
|
|||||||
default { throw "No match found for test: $Rec" }
|
default { throw "No match found for test: $Rec" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
throw "Get-CISMgOutput: `n$_"
|
||||||
|
}
|
||||||
|
}
|
||||||
end {
|
end {
|
||||||
Write-Verbose "Retuning data for Rec: $Rec"
|
Write-Verbose "Retuning data for Rec: $Rec"
|
||||||
}
|
}
|
||||||
|
@@ -1,200 +1,161 @@
|
|||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
This is a sample Private function only visible within the module.
|
Retrieves configuration settings from SharePoint Online or PnP based on the specified recommendation.
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This sample function is not exported to the module and only return the data passed as parameter.
|
The Get-CISSpoOutput function retrieves specific configuration settings from SharePoint Online or PnP based on a recommendation number.
|
||||||
|
It dynamically switches between using SPO and PnP commands based on the provided authentication context.
|
||||||
|
.PARAMETER Rec
|
||||||
|
The recommendation number corresponding to the specific test to be run.
|
||||||
|
.INPUTS
|
||||||
|
None. You cannot pipe objects to this function.
|
||||||
|
.OUTPUTS
|
||||||
|
PSCustomObject
|
||||||
|
Returns configuration details for the specified recommendation.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
$null = Get-CISSpoOutput -PrivateData 'NOTHING TO SEE HERE'
|
PS> Get-CISSpoOutput -Rec '7.2.1'
|
||||||
.PARAMETER PrivateData
|
Retrieves the LegacyAuthProtocolsEnabled property from the SharePoint Online or PnP tenant.
|
||||||
The PrivateData parameter is what will be returned without transformation.
|
|
||||||
#>
|
#>
|
||||||
function Get-CISSpoOutput {
|
function Get-CISSpoOutput {
|
||||||
[cmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, HelpMessage = "The recommendation number corresponding to the specific test to be run.")]
|
||||||
[String]$Rec
|
[String]$Rec
|
||||||
)
|
)
|
||||||
begin {
|
begin {
|
||||||
# Begin Block #
|
# Check if PnP should be used
|
||||||
<#
|
$UsePnP = $script:PnpAuth
|
||||||
# Tests
|
# Determine the prefix based on the switch
|
||||||
7.2.1
|
$prefix = if ($UsePnP) { "PnP" } else { "SPO" }
|
||||||
7.2.2
|
# Define a hashtable to map the function calls
|
||||||
7.2.3
|
$commandMap = @{
|
||||||
7.2.4
|
|
||||||
7.2.5
|
|
||||||
7.2.6
|
|
||||||
7.2.7
|
|
||||||
7.2.9
|
|
||||||
7.2.10
|
|
||||||
7.3.1
|
|
||||||
7.3.2
|
|
||||||
7.3.4
|
|
||||||
|
|
||||||
# Test number array
|
|
||||||
$testNumbers = @('7.2.1', '7.2.2', '7.2.3', '7.2.4', '7.2.5', '7.2.6', '7.2.7', '7.2.9', '7.2.10', '7.3.1', '7.3.2', '7.3.4')
|
|
||||||
#>
|
|
||||||
}
|
|
||||||
process {
|
|
||||||
Write-Verbose "Retuning data for Rec: $Rec"
|
|
||||||
switch ($Rec) {
|
|
||||||
'7.2.1' {
|
|
||||||
# Test-ModernAuthSharePoint.ps1
|
# Test-ModernAuthSharePoint.ps1
|
||||||
|
# 7.2.1 (L1) Ensure Legacy Authentication Protocols are disabled
|
||||||
# $SPOTenant Mock Object
|
# $SPOTenant Mock Object
|
||||||
<#
|
'7.2.1' = {
|
||||||
$SPOTenant = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
LegacyAuthProtocolsEnabled = $true
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
|
} | Select-Object -Property LegacyAuthProtocolsEnabled
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenant = Get-SPOTenant | Select-Object -Property LegacyAuthProtocolsEnabled
|
|
||||||
return $SPOTenant
|
|
||||||
}
|
|
||||||
'7.2.2' {
|
|
||||||
# Test-SharePointAADB2B.ps1
|
# Test-SharePointAADB2B.ps1
|
||||||
# 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled
|
# 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled
|
||||||
# $SPOTenantAzureADB2B Mock Object
|
# $SPOTenantAzureADB2B Mock Object
|
||||||
<#
|
'7.2.2' = {
|
||||||
$SPOTenantAzureADB2B = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
EnableAzureADB2BIntegration = $false
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
|
} | Select-Object -Property EnableAzureADB2BIntegration
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenantAzureADB2B = Get-SPOTenant | Select-Object EnableAzureADB2BIntegration
|
|
||||||
return $SPOTenantAzureADB2B
|
|
||||||
}
|
|
||||||
'7.2.3' {
|
|
||||||
# Test-RestrictExternalSharing.ps1
|
# Test-RestrictExternalSharing.ps1
|
||||||
# 7.2.3 (L1) Ensure external content sharing is restricted
|
# 7.2.3 (L1) Ensure external content sharing is restricted
|
||||||
# Retrieve the SharingCapability setting for the SharePoint tenant
|
# Retrieve the SharingCapability setting for the SharePoint tenant
|
||||||
# $SPOTenantSharingCapability Mock Object
|
# $SPOTenantSharingCapability Mock Object
|
||||||
<#
|
'7.2.3' = {
|
||||||
$SPOTenantSharingCapability = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
SharingCapability = "ExternalUserAndGuestSharing"
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
|
} | Select-Object -Property SharingCapability
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenantSharingCapability = Get-SPOTenant | Select-Object SharingCapability
|
|
||||||
return $SPOTenantSharingCapability
|
|
||||||
}
|
|
||||||
'7.2.4' {
|
|
||||||
# Test-OneDriveContentRestrictions.ps1
|
# Test-OneDriveContentRestrictions.ps1
|
||||||
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
|
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
|
||||||
# $SPOTenant Mock Object
|
# $SPOTenant Mock Object
|
||||||
<#
|
'7.2.4' = {
|
||||||
$SPOTenant = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
OneDriveSharingCapability = "ExternalUserAndGuestSharing"
|
if ($prefix -eq "SPO") {
|
||||||
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)" | Select-Object -Property OneDriveSharingCapability
|
||||||
|
} else {
|
||||||
|
# Workaround until bugfix in PnP.PowerShell
|
||||||
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)" | Select-Object -Property OneDriveLoopSharingCapability | Select-Object @{Name = "OneDriveSharingCapability"; Expression = { $_.OneDriveLoopSharingCapability }}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenant = Get-SPOTenant | Select-Object OneDriveSharingCapability
|
|
||||||
return $SPOTenant
|
|
||||||
}
|
}
|
||||||
'7.2.5' {
|
|
||||||
# Test-SharePointGuestsItemSharing.ps1
|
# Test-SharePointGuestsItemSharing.ps1
|
||||||
# 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own
|
# 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own
|
||||||
# $SPOTenant Mock Object
|
# $SPOTenant Mock Object
|
||||||
<#
|
'7.2.5' = {
|
||||||
$SPOTenant = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
PreventExternalUsersFromResharing = $false
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
|
} | Select-Object -Property PreventExternalUsersFromResharing
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenant = Get-SPOTenant | Select-Object PreventExternalUsersFromResharing
|
|
||||||
return $SPOTenant
|
|
||||||
}
|
|
||||||
'7.2.6' {
|
|
||||||
# Test-SharePointExternalSharingDomains.ps1
|
# Test-SharePointExternalSharingDomains.ps1
|
||||||
# 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists
|
# 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists
|
||||||
# Add Authorized Domains?
|
# Add Authorized Domains?
|
||||||
# $SPOTenant Mock Object
|
# $SPOTenant Mock Object
|
||||||
<#
|
'7.2.6' = {
|
||||||
$SPOTenant = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
SharingDomainRestrictionMode = "AllowList"
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
SharingAllowedDomainList = "domain1.com", "domain2.com"
|
} | Select-Object -Property SharingDomainRestrictionMode, SharingAllowedDomainList
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenant = Get-SPOTenant | Select-Object SharingDomainRestrictionMode, SharingAllowedDomainList
|
|
||||||
return $SPOTenant
|
|
||||||
}
|
|
||||||
'7.2.7' {
|
|
||||||
# Test-LinkSharingRestrictions.ps1
|
# Test-LinkSharingRestrictions.ps1
|
||||||
# Retrieve link sharing configuration for SharePoint and OneDrive
|
# Retrieve link sharing configuration for SharePoint and OneDrive
|
||||||
# $SPOTenantLinkSharing Mock Object
|
# $SPOTenantLinkSharing Mock Object
|
||||||
<#
|
'7.2.7' = {
|
||||||
$$SPOTenantLinkSharing = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
DefaultSharingLinkType = "Direct"
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
|
} | Select-Object -Property DefaultSharingLinkType
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenantLinkSharing = Get-SPOTenant | Select-Object DefaultSharingLinkType
|
|
||||||
return $SPOTenantLinkSharing
|
|
||||||
}
|
|
||||||
'7.2.9' {
|
|
||||||
# Test-GuestAccessExpiration.ps1
|
# Test-GuestAccessExpiration.ps1
|
||||||
# Retrieve SharePoint tenant settings related to guest access expiration
|
# Retrieve SharePoint tenant settings related to guest access expiration
|
||||||
# $SPOTenantGuestAccess Mock Object
|
# $SPOTenantGuestAccess Mock Object
|
||||||
<#
|
'7.2.9' = {
|
||||||
$SPOTenantGuestAccess = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
ExternalUserExpirationRequired = "$false"
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
ExternalUserExpireInDays = "60"
|
} | Select-Object -Property ExternalUserExpirationRequired, ExternalUserExpireInDays
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenantGuestAccess = Get-SPOTenant | Select-Object ExternalUserExpirationRequired, ExternalUserExpireInDays
|
|
||||||
return $SPOTenantGuestAccess
|
|
||||||
}
|
|
||||||
'7.2.10' {
|
|
||||||
# Test-ReauthWithCode.ps1
|
# Test-ReauthWithCode.ps1
|
||||||
# 7.2.10 (L1) Ensure reauthentication with verification code is restricted
|
# 7.2.10 (L1) Ensure reauthentication with verification code is restricted
|
||||||
# Retrieve reauthentication settings for SharePoint Online
|
# Retrieve reauthentication settings for SharePoint Online
|
||||||
# $SPOTenantReauthentication Mock Object
|
# $SPOTenantReauthentication Mock Object
|
||||||
<#
|
'7.2.10' = {
|
||||||
$SPOTenantReauthentication = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
EmailAttestationRequired = "$false"
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
EmailAttestationReAuthDays = "30"
|
} | Select-Object -Property EmailAttestationRequired, EmailAttestationReAuthDays
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenantReauthentication = Get-SPOTenant | Select-Object EmailAttestationRequired, EmailAttestationReAuthDays
|
|
||||||
return $SPOTenantReauthentication
|
|
||||||
}
|
|
||||||
'7.3.1' {
|
|
||||||
# Test-DisallowInfectedFilesDownload.ps1
|
# Test-DisallowInfectedFilesDownload.ps1
|
||||||
# Retrieve the SharePoint tenant configuration
|
# Retrieve the SharePoint tenant configuration
|
||||||
# $SPOTenantDisallowInfectedFileDownload Mock Object
|
# $SPOTenantDisallowInfectedFileDownload Mock Object
|
||||||
<#
|
'7.3.1' = {
|
||||||
$SPOTenantDisallowInfectedFileDownload = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
DisallowInfectedFileDownload = $false
|
& "$((Get-Command -Name "Get-${prefix}Tenant").Name)"
|
||||||
|
} | Select-Object -Property DisallowInfectedFileDownload
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenantDisallowInfectedFileDownload = Get-SPOTenant | Select-Object DisallowInfectedFileDownload
|
|
||||||
return $SPOTenantDisallowInfectedFileDownload
|
|
||||||
}
|
|
||||||
'7.3.2' {
|
|
||||||
# Test-OneDriveSyncRestrictions.ps1
|
# Test-OneDriveSyncRestrictions.ps1
|
||||||
# Retrieve OneDrive sync client restriction settings
|
# Retrieve OneDrive sync client restriction settings
|
||||||
# Add isHybrid paramter?
|
# Add isHybrid parameter?
|
||||||
# $SPOTenantSyncClientRestriction Mock Object
|
# $SPOTenantSyncClientRestriction Mock Object
|
||||||
<#
|
'7.3.2' = {
|
||||||
$SPOTenantSyncClientRestriction = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
TenantRestrictionEnabled = $true
|
& "$((Get-Command -Name "Get-${prefix}TenantSyncClientRestriction").Name)"
|
||||||
AllowedDomainList = "786548DD-877B-4760-A749-6B1EFBC1190A", "877564FF-877B-4760-A749-6B1EFBC1190A"
|
} | Select-Object -Property TenantRestrictionEnabled, AllowedDomainList
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOTenantSyncClientRestriction = Get-SPOTenantSyncClientRestriction | Select-Object TenantRestrictionEnabled, AllowedDomainList
|
|
||||||
return $SPOTenantSyncClientRestriction
|
|
||||||
}
|
|
||||||
'7.3.4' {
|
|
||||||
# Test-RestrictCustomScripts.ps1
|
# Test-RestrictCustomScripts.ps1
|
||||||
# Retrieve all site collections and select necessary properties
|
# Retrieve all site collections and select necessary properties
|
||||||
# $SPOSitesCustomScript Mock Object
|
# $SPOSitesCustomScript Mock Object
|
||||||
<#
|
'7.3.4' = {
|
||||||
$SPOSitesCustomScript = [PSCustomObject]@{
|
Invoke-Command {
|
||||||
Title = "Site Collection 1"
|
if ($prefix -eq "SPO") {
|
||||||
Url = "https://contoso.sharepoint.com/sites/site1"
|
& "$((Get-Command -Name "Get-${prefix}Site").Name)" -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages
|
||||||
DenyAddAndCustomizePages = "Enabled"
|
} else {
|
||||||
|
& "$((Get-Command -Name "Get-${prefix}TenantSite").Name)" | Select-Object Title, Url, DenyAddAndCustomizePages
|
||||||
}
|
}
|
||||||
#>
|
|
||||||
$SPOSitesCustomScript = Get-SPOSite -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages
|
|
||||||
return $SPOSitesCustomScript
|
|
||||||
}
|
}
|
||||||
default { throw "No match found for test: $Rec" }
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process {
|
||||||
|
try {
|
||||||
|
Write-Verbose "Returning data for Rec: $Rec"
|
||||||
|
if ($commandMap.ContainsKey($Rec)) {
|
||||||
|
# Invoke the script block associated with the command
|
||||||
|
$result = & $commandMap[$Rec] -ErrorAction Stop
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "No match found for test: $Rec"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw "Get-CISSpoOutput: `n$_"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end {
|
end {
|
||||||
Write-Verbose "Retuning data for Rec: $Rec"
|
Write-Verbose "Finished processing for Rec: $Rec"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} # end function Get-CISMSTeamsOutput
|
|
@@ -4,21 +4,28 @@ function Get-RequiredModule {
|
|||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = 'AuditFunction')]
|
[Parameter(Mandatory = $true, ParameterSetName = 'AuditFunction')]
|
||||||
[switch]$AuditFunction,
|
[switch]$AuditFunction,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = 'SyncFunction')]
|
[Parameter(Mandatory = $true, ParameterSetName = 'SyncFunction')]
|
||||||
[switch]$SyncFunction
|
[switch]$SyncFunction
|
||||||
)
|
)
|
||||||
|
|
||||||
switch ($PSCmdlet.ParameterSetName) {
|
switch ($PSCmdlet.ParameterSetName) {
|
||||||
'AuditFunction' {
|
'AuditFunction' {
|
||||||
|
if (($script:PnpAuth)) {
|
||||||
return @(
|
return @(
|
||||||
@{ ModuleName = "ExchangeOnlineManagement"; RequiredVersion = "3.3.0"; SubModules = @() },
|
@{ ModuleName = "ExchangeOnlineManagement"; RequiredVersion = "3.3.0"; SubModules = @() },
|
||||||
@{ ModuleName = "AzureAD"; RequiredVersion = "2.0.2.182"; SubModules = @() },
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModules = @("DeviceManagement", "Users", "Identity.DirectoryManagement", "Identity.SignIns") },
|
||||||
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModules = @("Groups", "DeviceManagement", "Users", "Identity.DirectoryManagement", "Identity.SignIns") },
|
@{ ModuleName = "PnP.PowerShell"; RequiredVersion = "2.5.0"; SubModules = @() },
|
||||||
|
@{ ModuleName = "MicrosoftTeams"; RequiredVersion = "5.5.0"; SubModules = @() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return @(
|
||||||
|
@{ ModuleName = "ExchangeOnlineManagement"; RequiredVersion = "3.3.0"; SubModules = @() },
|
||||||
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModules = @("DeviceManagement", "Users", "Identity.DirectoryManagement", "Identity.SignIns") },
|
||||||
@{ ModuleName = "Microsoft.Online.SharePoint.PowerShell"; RequiredVersion = "16.0.24009.12000"; SubModules = @() },
|
@{ ModuleName = "Microsoft.Online.SharePoint.PowerShell"; RequiredVersion = "16.0.24009.12000"; SubModules = @() },
|
||||||
@{ ModuleName = "MicrosoftTeams"; RequiredVersion = "5.5.0"; SubModules = @() }
|
@{ ModuleName = "MicrosoftTeams"; RequiredVersion = "5.5.0"; SubModules = @() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
'SyncFunction' {
|
'SyncFunction' {
|
||||||
return @(
|
return @(
|
||||||
@{ ModuleName = "ImportExcel"; RequiredVersion = "7.8.9"; SubModules = @() }
|
@{ ModuleName = "ImportExcel"; RequiredVersion = "7.8.9"; SubModules = @() }
|
||||||
|
@@ -27,7 +27,7 @@ function Get-TestError {
|
|||||||
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $LastError })
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $LastError })
|
||||||
# Call Initialize-CISAuditResult with error parameters
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
Write-Verbose "An error occurred during the test: `n$LastError" -Verbose
|
Write-Verbose "An error occurred during the test $recnum`: `n$LastError" -Verbose
|
||||||
return $auditResult
|
return $auditResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,10 +8,7 @@ function Get-UniqueConnection {
|
|||||||
|
|
||||||
$uniqueConnections = @()
|
$uniqueConnections = @()
|
||||||
|
|
||||||
if ($Connections -contains "AzureAD" -or $Connections -contains "AzureAD | EXO" -or $Connections -contains "AzureAD | EXO | Microsoft Graph") {
|
if ($Connections -contains "Microsoft Graph" -or $Connections -contains "AzureAD | EXO | Microsoft Graph" -or $Connections -contains "EXO | Microsoft Graph") {
|
||||||
$uniqueConnections += "AzureAD"
|
|
||||||
}
|
|
||||||
if ($Connections -contains "Microsoft Graph" -or $Connections -contains "AzureAD | EXO | Microsoft Graph") {
|
|
||||||
$uniqueConnections += "Microsoft Graph"
|
$uniqueConnections += "Microsoft Graph"
|
||||||
}
|
}
|
||||||
if ($Connections -contains "EXO" -or $Connections -contains "AzureAD | EXO" -or $Connections -contains "Microsoft Teams | EXO" -or $Connections -contains "AzureAD | EXO | Microsoft Graph") {
|
if ($Connections -contains "EXO" -or $Connections -contains "AzureAD | EXO" -or $Connections -contains "Microsoft Teams | EXO" -or $Connections -contains "AzureAD | EXO | Microsoft Graph") {
|
||||||
|
@@ -33,7 +33,7 @@ function Invoke-TestFunction {
|
|||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred during the test: $_"
|
Write-Error "An error occurred during the test $recnum`:: $_"
|
||||||
$script:FailedTests.Add([PSCustomObject]@{ Test = $functionName; Error = $_ })
|
$script:FailedTests.Add([PSCustomObject]@{ Test = $functionName; Error = $_ })
|
||||||
|
|
||||||
# Call Initialize-CISAuditResult with error parameters
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
@@ -18,15 +18,15 @@ function Measure-AuditResult {
|
|||||||
$passPercentage = if ($totalTests -eq 0) { 0 } else { [math]::Round(($passedTests / $totalTests) * 100, 2) }
|
$passPercentage = if ($totalTests -eq 0) { 0 } else { [math]::Round(($passedTests / $totalTests) * 100, 2) }
|
||||||
|
|
||||||
# Display the pass percentage to the user
|
# Display the pass percentage to the user
|
||||||
Write-Host "Audit completed. $passedTests out of $totalTests tests passed." -ForegroundColor Cyan
|
Write-Information "Audit completed. $passedTests out of $totalTests tests passed."
|
||||||
Write-Host "Your passing percentage is $passPercentage%." -ForegroundColor Magenta
|
Write-Information "Your passing percentage is $passPercentage%."
|
||||||
|
|
||||||
# Display details of failed tests
|
# Display details of failed tests
|
||||||
if ($FailedTests.Count -gt 0) {
|
if ($FailedTests.Count -gt 0) {
|
||||||
Write-Host "The following tests failed to complete:" -ForegroundColor Red
|
Write-Verbose "The following tests failed to complete:"
|
||||||
foreach ($failedTest in $FailedTests) {
|
foreach ($failedTest in $FailedTests) {
|
||||||
Write-Host "Test: $($failedTest.Test)" -ForegroundColor Yellow
|
Write-Verbose "Test: $($failedTest.Test)"
|
||||||
Write-Host "Error: $($failedTest.Error)" -ForegroundColor Yellow
|
Write-Verbose "Error: $($failedTest.Error)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
The path to a CSV file containing the audit results. This parameter is mandatory when exporting from a CSV file.
|
The path to a CSV file containing the audit results. This parameter is mandatory when exporting from a CSV file.
|
||||||
.PARAMETER OutputTestNumber
|
.PARAMETER OutputTestNumber
|
||||||
The test number to output as an object. Valid values are "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4". This parameter is used to output a specific test result.
|
The test number to output as an object. Valid values are "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4". This parameter is used to output a specific test result.
|
||||||
.PARAMETER ExportAllTests
|
.PARAMETER ExportNestedTables
|
||||||
Switch to export all test results. When specified, all test results are exported to the specified path.
|
Switch to export all test results. When specified, all test results are exported to the specified path.
|
||||||
.PARAMETER ExportPath
|
.PARAMETER ExportPath
|
||||||
The path where the CSV or Excel files will be exported. This parameter is mandatory when exporting all tests.
|
The path where the CSV or Excel files will be exported. This parameter is mandatory when exporting all tests.
|
||||||
@@ -28,28 +28,28 @@
|
|||||||
Export-M365SecurityAuditTable -AuditResults $object -OutputTestNumber 6.1.2
|
Export-M365SecurityAuditTable -AuditResults $object -OutputTestNumber 6.1.2
|
||||||
# Outputs the result of test number 6.1.2 from the provided audit results as an object.
|
# Outputs the result of test number 6.1.2 from the provided audit results as an object.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Export-M365SecurityAuditTable -ExportAllTests -AuditResults $object -ExportPath "C:\temp"
|
Export-M365SecurityAuditTable -ExportNestedTables -AuditResults $object -ExportPath "C:\temp"
|
||||||
# Exports all audit results to the specified path in CSV format.
|
# Exports all audit results to the specified path in CSV format.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Export-M365SecurityAuditTable -CsvPath "C:\temp\auditresultstoday1.csv" -OutputTestNumber 6.1.2
|
Export-M365SecurityAuditTable -CsvPath "C:\temp\auditresultstoday1.csv" -OutputTestNumber 6.1.2
|
||||||
# Outputs the result of test number 6.1.2 from the CSV file as an object.
|
# Outputs the result of test number 6.1.2 from the CSV file as an object.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Export-M365SecurityAuditTable -ExportAllTests -CsvPath "C:\temp\auditresultstoday1.csv" -ExportPath "C:\temp"
|
Export-M365SecurityAuditTable -ExportNestedTables -CsvPath "C:\temp\auditresultstoday1.csv" -ExportPath "C:\temp"
|
||||||
# Exports all audit results from the CSV file to the specified path in CSV format.
|
# Exports all audit results from the CSV file to the specified path in CSV format.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Export-M365SecurityAuditTable -ExportAllTests -AuditResults $object -ExportPath "C:\temp" -ExportOriginalTests
|
Export-M365SecurityAuditTable -ExportNestedTables -AuditResults $object -ExportPath "C:\temp" -ExportOriginalTests
|
||||||
# Exports all audit results along with the original test results to the specified path in CSV format.
|
# Exports all audit results along with the original test results to the specified path in CSV format.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Export-M365SecurityAuditTable -ExportAllTests -CsvPath "C:\temp\auditresultstoday1.csv" -ExportPath "C:\temp" -ExportOriginalTests
|
Export-M365SecurityAuditTable -ExportNestedTables -CsvPath "C:\temp\auditresultstoday1.csv" -ExportPath "C:\temp" -ExportOriginalTests
|
||||||
# Exports all audit results from the CSV file along with the original test results to the specified path in CSV format.
|
# Exports all audit results from the CSV file along with the original test results to the specified path in CSV format.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Export-M365SecurityAuditTable -ExportAllTests -AuditResults $object -ExportPath "C:\temp" -ExportToExcel
|
Export-M365SecurityAuditTable -ExportNestedTables -AuditResults $object -ExportPath "C:\temp" -ExportToExcel
|
||||||
# Exports all audit results to the specified path in Excel format.
|
# Exports all audit results to the specified path in Excel format.
|
||||||
.LINK
|
.LINK
|
||||||
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Export-M365SecurityAuditTable
|
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Export-M365SecurityAuditTable
|
||||||
#>
|
#>
|
||||||
function Export-M365SecurityAuditTable {
|
function Export-M365SecurityAuditTable {
|
||||||
[CmdletBinding()]
|
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
|
||||||
[OutputType([PSCustomObject])]
|
[OutputType([PSCustomObject])]
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||||
@@ -65,22 +65,31 @@ function Export-M365SecurityAuditTable {
|
|||||||
[string]$OutputTestNumber,
|
[string]$OutputTestNumber,
|
||||||
[Parameter(Mandatory = $false, Position = 0, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
[Parameter(Mandatory = $false, Position = 0, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||||
[Parameter(Mandatory = $false, Position = 0, ParameterSetName = "ExportAllResultsFromCsv")]
|
[Parameter(Mandatory = $false, Position = 0, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||||
[switch]$ExportAllTests,
|
[switch]$ExportNestedTables,
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromCsv")]
|
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||||
[string]$ExportPath,
|
[string]$ExportPath,
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromCsv")]
|
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||||
[switch]$ExportOriginalTests,
|
[switch]$ExportOriginalTests,
|
||||||
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||||
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromCsv")]
|
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||||
[switch]$ExportToExcel
|
[switch]$ExportToExcel,
|
||||||
|
# Add Prefix to filename after date when outputting to excel or csv.
|
||||||
|
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||||
|
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||||
|
# Validate that the count of letters in the prefix is less than 5.
|
||||||
|
[ValidateLength(0, 5)]
|
||||||
|
[string]$Prefix = "Corp"
|
||||||
)
|
)
|
||||||
Begin {
|
Begin {
|
||||||
$createdFiles = @() # Initialize an array to keep track of created files
|
$createdFiles = @() # Initialize an array to keep track of created files
|
||||||
|
|
||||||
if ($ExportToExcel) {
|
if ($ExportToExcel) {
|
||||||
|
if ($PSCmdlet.ShouldProcess("ImportExcel v7.8.9", "Assert-ModuleAvailability")) {
|
||||||
Assert-ModuleAvailability -ModuleName ImportExcel -RequiredVersion "7.8.9"
|
Assert-ModuleAvailability -ModuleName ImportExcel -RequiredVersion "7.8.9"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ($PSCmdlet.ParameterSetName -like "ExportAllResultsFromCsv" -or $PSCmdlet.ParameterSetName -eq "OutputObjectFromCsvSingle") {
|
if ($PSCmdlet.ParameterSetName -like "ExportAllResultsFromCsv" -or $PSCmdlet.ParameterSetName -eq "OutputObjectFromCsvSingle") {
|
||||||
$AuditResults = Import-Csv -Path $CsvPath | ForEach-Object {
|
$AuditResults = Import-Csv -Path $CsvPath | ForEach-Object {
|
||||||
$params = @{
|
$params = @{
|
||||||
@@ -93,7 +102,7 @@ function Export-M365SecurityAuditTable {
|
|||||||
Initialize-CISAuditResult @params
|
Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($ExportAllTests) {
|
if ($ExportNestedTables) {
|
||||||
$TestNumbers = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
$TestNumbers = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
||||||
}
|
}
|
||||||
$results = @()
|
$results = @()
|
||||||
@@ -127,6 +136,7 @@ function Export-M365SecurityAuditTable {
|
|||||||
}
|
}
|
||||||
End {
|
End {
|
||||||
if ($ExportPath) {
|
if ($ExportPath) {
|
||||||
|
if ($PSCmdlet.ShouldProcess("Export-M365SecurityAuditTable", "Exporting results to $ExportPath")) {
|
||||||
$timestamp = (Get-Date).ToString("yyyy.MM.dd_HH.mm.ss")
|
$timestamp = (Get-Date).ToString("yyyy.MM.dd_HH.mm.ss")
|
||||||
$exportedTests = @()
|
$exportedTests = @()
|
||||||
foreach ($result in $results) {
|
foreach ($result in $results) {
|
||||||
@@ -134,7 +144,7 @@ function Export-M365SecurityAuditTable {
|
|||||||
if ($testDef) {
|
if ($testDef) {
|
||||||
$fileName = "$ExportPath\$($timestamp)_$($result.TestNumber).$($testDef.TestFileName -replace '\.ps1$').csv"
|
$fileName = "$ExportPath\$($timestamp)_$($result.TestNumber).$($testDef.TestFileName -replace '\.ps1$').csv"
|
||||||
if ($result.Details.Count -eq 0) {
|
if ($result.Details.Count -eq 0) {
|
||||||
Write-Information "No results found for test number $($result.TestNumber)." -InformationAction Continue
|
Write-Information "No results found for test number $($result.TestNumber)."
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (($result.Details -ne "No M365 E3 licenses found.") -and ($result.Details -ne "No M365 E5 licenses found.")) {
|
if (($result.Details -ne "No M365 E3 licenses found.") -and ($result.Details -ne "No M365 E5 licenses found.")) {
|
||||||
@@ -153,14 +163,14 @@ function Export-M365SecurityAuditTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($exportedTests.Count -gt 0) {
|
if ($exportedTests.Count -gt 0) {
|
||||||
Write-Information "The following tests were exported: $($exportedTests -join ', ')" -InformationAction Continue
|
Write-Information "The following tests were exported: $($exportedTests -join ', ')"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ($ExportOriginalTests) {
|
if ($ExportOriginalTests) {
|
||||||
Write-Information "Full audit results exported however, none of the following tests had exports: `n1.1.1, 1.3.1, 6.1.2, 6.1.3, 7.3.4" -InformationAction Continue
|
Write-Information "Full audit results exported however, none of the following tests had exports: `n1.1.1, 1.3.1, 6.1.2, 6.1.3, 7.3.4"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Information "No specified tests were included in the export." -InformationAction Continue
|
Write-Information "No specified tests were included in the export."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($ExportOriginalTests) {
|
if ($ExportOriginalTests) {
|
||||||
@@ -168,7 +178,7 @@ function Export-M365SecurityAuditTable {
|
|||||||
$TestNumbersToCheck = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
$TestNumbersToCheck = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
||||||
# Check for large details and update the AuditResults array
|
# Check for large details and update the AuditResults array
|
||||||
$updatedAuditResults = Get-ExceededLengthResultDetail -AuditResults $AuditResults -TestNumbersToCheck $TestNumbersToCheck -ExportedTests $exportedTests -DetailsLengthLimit 30000 -PreviewLineCount 25
|
$updatedAuditResults = Get-ExceededLengthResultDetail -AuditResults $AuditResults -TestNumbersToCheck $TestNumbersToCheck -ExportedTests $exportedTests -DetailsLengthLimit 30000 -PreviewLineCount 25
|
||||||
$originalFileName = "$ExportPath\$timestamp`_M365FoundationsAudit.csv"
|
$originalFileName = "$ExportPath\$timestamp`_$Prefix-M365FoundationsAudit.csv"
|
||||||
if ($ExportToExcel) {
|
if ($ExportToExcel) {
|
||||||
$xlsxPath = [System.IO.Path]::ChangeExtension($originalFileName, '.xlsx')
|
$xlsxPath = [System.IO.Path]::ChangeExtension($originalFileName, '.xlsx')
|
||||||
$updatedAuditResults | Export-Excel -Path $xlsxPath -WorksheetName Table -TableName Table -AutoSize -TableStyle Medium2
|
$updatedAuditResults | Export-Excel -Path $xlsxPath -WorksheetName Table -TableName Table -AutoSize -TableStyle Medium2
|
||||||
@@ -189,32 +199,29 @@ function Export-M365SecurityAuditTable {
|
|||||||
}
|
}
|
||||||
$fileHashes | Set-Content -Path $hashFilePath
|
$fileHashes | Set-Content -Path $hashFilePath
|
||||||
$createdFiles += $hashFilePath # Add the hash file to the array
|
$createdFiles += $hashFilePath # Add the hash file to the array
|
||||||
|
|
||||||
# Create a zip file and add all the created files
|
# Create a zip file and add all the created files
|
||||||
$zipFilePath = "$ExportPath\$timestamp`_M365FoundationsAudit.zip"
|
$zipFilePath = "$ExportPath\$timestamp`_$Prefix-M365FoundationsAudit.zip"
|
||||||
Compress-Archive -Path $createdFiles -DestinationPath $zipFilePath
|
Compress-Archive -Path $createdFiles -DestinationPath $zipFilePath
|
||||||
|
|
||||||
# Remove the original files after they have been added to the zip
|
# Remove the original files after they have been added to the zip
|
||||||
foreach ($file in $createdFiles) {
|
foreach ($file in $createdFiles) {
|
||||||
Remove-Item -Path $file -Force
|
Remove-Item -Path $file -Force
|
||||||
}
|
}
|
||||||
|
|
||||||
# Compute the hash for the zip file and rename it
|
# Compute the hash for the zip file and rename it
|
||||||
$zipHash = Get-FileHash -Path $zipFilePath -Algorithm SHA256
|
$zipHash = Get-FileHash -Path $zipFilePath -Algorithm SHA256
|
||||||
$newZipFilePath = "$ExportPath\$timestamp`_M365FoundationsAudit_$($zipHash.Hash.Substring(0, 8)).zip"
|
$newZipFilePath = "$ExportPath\$timestamp`_$Prefix-M365FoundationsAudit_$($zipHash.Hash.Substring(0, 8)).zip"
|
||||||
Rename-Item -Path $zipFilePath -NewName $newZipFilePath
|
Rename-Item -Path $zipFilePath -NewName $newZipFilePath
|
||||||
|
|
||||||
# Output the zip file path with hash
|
# Output the zip file path with hash
|
||||||
[PSCustomObject]@{
|
return [PSCustomObject]@{
|
||||||
ZipFilePath = $newZipFilePath
|
ZipFilePath = $newZipFilePath
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} # End of ExportPath
|
} # End of ExportPath
|
||||||
elseif ($OutputTestNumber) {
|
elseif ($OutputTestNumber) {
|
||||||
if ($results[0].Details) {
|
if ($results[0].Details) {
|
||||||
return $results[0].Details
|
return $results[0].Details
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Information "No results found for test number $($OutputTestNumber)." -InformationAction Continue
|
Write-Information "No results found for test number $($OutputTestNumber)."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -37,91 +37,42 @@
|
|||||||
If specified, the cmdlet will not check for the presence of required modules.
|
If specified, the cmdlet will not check for the presence of required modules.
|
||||||
.PARAMETER DoNotConfirmConnections
|
.PARAMETER DoNotConfirmConnections
|
||||||
If specified, the cmdlet will not prompt for confirmation before proceeding with established connections and will disconnect from all of them.
|
If specified, the cmdlet will not prompt for confirmation before proceeding with established connections and will disconnect from all of them.
|
||||||
|
.PARAMETER AuthParams
|
||||||
|
Specifies an authentication object containing parameters for application-based authentication. If provided, this will be used for connecting to services.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
PS> Invoke-M365SecurityAudit
|
PS> Invoke-M365SecurityAudit
|
||||||
|
# Performs a security audit using default parameters.
|
||||||
Performs a security audit using default parameters.
|
|
||||||
Output:
|
|
||||||
|
|
||||||
Status : Fail
|
|
||||||
ELevel : E3
|
|
||||||
ProfileLevel: L1
|
|
||||||
Connection : Microsoft Graph
|
|
||||||
Rec : 1.1.1
|
|
||||||
Result : False
|
|
||||||
Details : Non-compliant accounts:
|
|
||||||
Username | Roles | HybridStatus | Missing Licence
|
|
||||||
user1@domain.com| Global Administrator | Cloud-Only | AAD_PREMIUM
|
|
||||||
user2@domain.com| Global Administrator | Hybrid | AAD_PREMIUM, AAD_PREMIUM_P2
|
|
||||||
FailureReason: Non-Compliant Accounts: 2
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
PS> Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com" -ELevel "E5" -ProfileLevel "L1"
|
PS> Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com" -ELevel "E5" -ProfileLevel "L1"
|
||||||
|
# Performs a security audit for the E5 level and L1 profile in the specified Microsoft 365 environment.
|
||||||
Performs a security audit for the E5 level and L1 profile in the specified Microsoft 365 environment.
|
|
||||||
Output:
|
|
||||||
|
|
||||||
Status : Fail
|
|
||||||
ELevel : E5
|
|
||||||
ProfileLevel: L1
|
|
||||||
Connection : Microsoft Graph
|
|
||||||
Rec : 1.1.1
|
|
||||||
Result : False
|
|
||||||
Details : Non-compliant accounts:
|
|
||||||
Username | Roles | HybridStatus | Missing Licence
|
|
||||||
user1@domain.com| Global Administrator | Cloud-Only | AAD_PREMIUM
|
|
||||||
user2@domain.com| Global Administrator | Hybrid | AAD_PREMIUM, AAD_PREMIUM_P2
|
|
||||||
FailureReason: Non-Compliant Accounts: 2
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
PS> Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com" -IncludeIG1
|
PS> Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com" -IncludeIG1
|
||||||
|
# Performs a security audit while including tests where IG1 is true.
|
||||||
Performs an audit including all tests where IG1 is true.
|
|
||||||
Output:
|
|
||||||
|
|
||||||
Status : Fail
|
|
||||||
ELevel : E3
|
|
||||||
ProfileLevel: L1
|
|
||||||
Connection : Microsoft Graph
|
|
||||||
Rec : 1.1.1
|
|
||||||
Result : False
|
|
||||||
Details : Non-compliant accounts:
|
|
||||||
Username | Roles | HybridStatus | Missing Licence
|
|
||||||
user1@domain.com| Global Administrator | Cloud-Only | AAD_PREMIUM
|
|
||||||
user2@domain.com| Global Administrator | Hybrid | AAD_PREMIUM, AAD_PREMIUM_P2
|
|
||||||
FailureReason: Non-Compliant Accounts: 2
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
PS> Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com" -SkipRecommendation '1.1.3', '2.1.1'
|
PS> Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com" -SkipRecommendation '1.1.3', '2.1.1'
|
||||||
|
# Performs an audit while excluding specific recommendations 1.1.3 and 2.1.1.
|
||||||
Performs an audit while excluding specific recommendations 1.1.3 and 2.1.1.
|
|
||||||
Output:
|
|
||||||
|
|
||||||
Status : Fail
|
|
||||||
ELevel : E3
|
|
||||||
ProfileLevel: L1
|
|
||||||
Connection : Microsoft Graph
|
|
||||||
Rec : 1.1.1
|
|
||||||
Result : False
|
|
||||||
Details : Non-compliant accounts:
|
|
||||||
Username | Roles | HybridStatus | Missing Licence
|
|
||||||
user1@domain.com| Global Administrator | Cloud-Only | AAD_PREMIUM
|
|
||||||
user2@domain.com| Global Administrator | Hybrid | AAD_PREMIUM, AAD_PREMIUM_P2
|
|
||||||
FailureReason: Non-Compliant Accounts: 2
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
PS> $auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com"
|
PS> $auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://contoso-admin.sharepoint.com" -DomainName "contoso.com"
|
||||||
PS> Export-M365SecurityAuditTable -AuditResults $auditResults -ExportPath "C:\temp" -ExportOriginalTests -ExportAllTests
|
PS> Export-M365SecurityAuditTable -AuditResults $auditResults -ExportPath "C:\temp" -ExportOriginalTests -ExportAllTests
|
||||||
|
.EXAMPLE
|
||||||
Or:
|
# (PowerShell 7.x Only) Creating a new authentication object for the security audit for app-based authentication.
|
||||||
|
PS> $authParams = New-M365SecurityAuditAuthObject `
|
||||||
|
-ClientCertThumbPrint "ABCDEF1234567890ABCDEF1234567890ABCDEF12" `
|
||||||
|
-ClientId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-TenantId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-OnMicrosoftUrl "yourcompany.onmicrosoft.com" `
|
||||||
|
-SpAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
|
Invoke-M365SecurityAudit -AuthParams $authParams -TenantAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
|
# Or:
|
||||||
PS> $auditResults | Export-Csv -Path "auditResults.csv" -NoTypeInformation
|
PS> $auditResults | Export-Csv -Path "auditResults.csv" -NoTypeInformation
|
||||||
|
# Captures the audit results into a variable and exports them to a CSV file (Nested tables will be truncated).
|
||||||
Captures the audit results into a variable and exports them to a CSV file (Nested tables will be truncated).
|
|
||||||
Output:
|
Output:
|
||||||
CISAuditResult[]
|
CISAuditResult[]
|
||||||
auditResults.csv
|
auditResults.csv
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
PS> Invoke-M365SecurityAudit -WhatIf
|
PS> Invoke-M365SecurityAudit -WhatIf
|
||||||
|
|
||||||
Displays what would happen if the cmdlet is run without actually performing the audit.
|
Displays what would happen if the cmdlet is run without actually performing the audit.
|
||||||
Output:
|
Output:
|
||||||
|
|
||||||
What if: Performing the operation "Invoke-M365SecurityAudit" on target "Microsoft 365 environment".
|
What if: Performing the operation "Invoke-M365SecurityAudit" on target "Microsoft 365 environment".
|
||||||
.INPUTS
|
.INPUTS
|
||||||
None. You cannot pipe objects to Invoke-M365SecurityAudit.
|
None. You cannot pipe objects to Invoke-M365SecurityAudit.
|
||||||
@@ -139,7 +90,8 @@
|
|||||||
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Invoke-M365SecurityAudit
|
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Invoke-M365SecurityAudit
|
||||||
#>
|
#>
|
||||||
function Invoke-M365SecurityAudit {
|
function Invoke-M365SecurityAudit {
|
||||||
[CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'Default')]
|
# Add confirm to high
|
||||||
|
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "High" , DefaultParameterSetName = 'Default')]
|
||||||
[OutputType([CISAuditResult[]])]
|
[OutputType([CISAuditResult[]])]
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $false, HelpMessage = "The SharePoint tenant admin URL, which should end with '-admin.sharepoint.com'. If not specified none of the Sharepoint Online tests will run.")]
|
[Parameter(Mandatory = $false, HelpMessage = "The SharePoint tenant admin URL, which should end with '-admin.sharepoint.com'. If not specified none of the Sharepoint Online tests will run.")]
|
||||||
@@ -202,20 +154,25 @@ function Invoke-M365SecurityAudit {
|
|||||||
[Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not check for the presence of required modules.")]
|
[Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not check for the presence of required modules.")]
|
||||||
[switch]$NoModuleCheck,
|
[switch]$NoModuleCheck,
|
||||||
[Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not prompt for confirmation before proceeding with established connections and will disconnect from all of them.")]
|
[Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not prompt for confirmation before proceeding with established connections and will disconnect from all of them.")]
|
||||||
[switch]$DoNotConfirmConnections
|
[switch]$DoNotConfirmConnections,
|
||||||
|
[Parameter(Mandatory = $false, HelpMessage = "Specifies an authentication object containing parameters for application-based authentication.")]
|
||||||
|
[CISAuthenticationParameters]$AuthParams
|
||||||
)
|
)
|
||||||
Begin {
|
Begin {
|
||||||
if ($script:MaximumFunctionCount -lt 8192) {
|
if ($script:MaximumFunctionCount -lt 8192) {
|
||||||
Write-Verbose "Setting the `$script:MaximumFunctionCount to 8192 for the test run." -Verbose
|
Write-Verbose "Setting the `$script:MaximumFunctionCount to 8192 for the test run."
|
||||||
$script:MaximumFunctionCount = 8192
|
$script:MaximumFunctionCount = 8192
|
||||||
}
|
}
|
||||||
|
if ($AuthParams) {
|
||||||
|
$script:PnpAuth = $true
|
||||||
|
}
|
||||||
# Ensure required modules are installed
|
# Ensure required modules are installed
|
||||||
$requiredModules = Get-RequiredModule -AuditFunction
|
$requiredModules = Get-RequiredModule -AuditFunction
|
||||||
# Format the required modules list
|
# Format the required modules list
|
||||||
$requiredModulesFormatted = Format-RequiredModuleList -RequiredModules $requiredModules
|
$requiredModulesFormatted = Format-RequiredModuleList -RequiredModules $requiredModules
|
||||||
# Check and install required modules if necessary
|
# Check and install required modules if necessary
|
||||||
if (!($NoModuleCheck) -and $PSCmdlet.ShouldProcess("Check for required modules: $requiredModulesFormatted", "Check")) {
|
if (!($NoModuleCheck) -and $PSCmdlet.ShouldProcess("Modules: $requiredModulesFormatted", "Assert-ModuleAvailability")) {
|
||||||
Write-Host "Checking for and installing required modules..." -ForegroundColor DarkMagenta
|
Write-Information "Checking for and installing required modules..."
|
||||||
foreach ($module in $requiredModules) {
|
foreach ($module in $requiredModules) {
|
||||||
Assert-ModuleAvailability -ModuleName $module.ModuleName -RequiredVersion $module.RequiredVersion -SubModules $module.SubModules
|
Assert-ModuleAvailability -ModuleName $module.ModuleName -RequiredVersion $module.RequiredVersion -SubModules $module.SubModules
|
||||||
}
|
}
|
||||||
@@ -265,16 +222,16 @@ function Invoke-M365SecurityAudit {
|
|||||||
try {
|
try {
|
||||||
$actualUniqueConnections = Get-UniqueConnection -Connections $requiredConnections
|
$actualUniqueConnections = Get-UniqueConnection -Connections $requiredConnections
|
||||||
if (!($DoNotConnect) -and $PSCmdlet.ShouldProcess("Establish connections to Microsoft 365 services: $($actualUniqueConnections -join ', ')", "Connect")) {
|
if (!($DoNotConnect) -and $PSCmdlet.ShouldProcess("Establish connections to Microsoft 365 services: $($actualUniqueConnections -join ', ')", "Connect")) {
|
||||||
Write-Host "Establishing connections to Microsoft 365 services: $($actualUniqueConnections -join ', ')" -ForegroundColor DarkMagenta
|
Write-Information "Establishing connections to Microsoft 365 services: $($actualUniqueConnections -join ', ')"
|
||||||
Connect-M365Suite -TenantAdminUrl $TenantAdminUrl -RequiredConnections $requiredConnections -SkipConfirmation:$DoNotConfirmConnections
|
Connect-M365Suite -TenantAdminUrl $TenantAdminUrl -RequiredConnections $requiredConnections -SkipConfirmation:$DoNotConfirmConnections -AuthParams $AuthParams
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Host "Connection execution aborted: $_" -ForegroundColor Red
|
Throw "Connection execution aborted: $_"
|
||||||
break
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Write-Host "A total of $($totalTests) tests were selected to run..." -ForegroundColor DarkMagenta
|
if ($PSCmdlet.ShouldProcess("Measure and display audit results for $($totalTests) tests", "Measure")) {
|
||||||
|
Write-Information "A total of $($totalTests) tests were selected to run..."
|
||||||
# Import the test functions
|
# Import the test functions
|
||||||
$testFiles | ForEach-Object {
|
$testFiles | ForEach-Object {
|
||||||
$currentTestIndex++
|
$currentTestIndex++
|
||||||
@@ -285,7 +242,7 @@ function Invoke-M365SecurityAudit {
|
|||||||
}
|
}
|
||||||
Catch {
|
Catch {
|
||||||
# Log the error and add the test to the failed tests collection
|
# Log the error and add the test to the failed tests collection
|
||||||
Write-Verbose "Failed to load test function $($_.Name): $_" -Verbose
|
Write-Verbose "Failed to load test function $($_.Name): $_"
|
||||||
$script:FailedTests.Add([PSCustomObject]@{ Test = $_.Name; Error = $_ })
|
$script:FailedTests.Add([PSCustomObject]@{ Test = $_.Name; Error = $_ })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,16 +252,29 @@ function Invoke-M365SecurityAudit {
|
|||||||
$currentTestIndex++
|
$currentTestIndex++
|
||||||
Write-Progress -Activity "Executing Tests" -Status "Executing $($currentTestIndex) of $($totalTests): $($testFunction.Name)" -PercentComplete (($currentTestIndex / $totalTests) * 100)
|
Write-Progress -Activity "Executing Tests" -Status "Executing $($currentTestIndex) of $($totalTests): $($testFunction.Name)" -PercentComplete (($currentTestIndex / $totalTests) * 100)
|
||||||
$functionName = $testFunction.BaseName
|
$functionName = $testFunction.BaseName
|
||||||
if ($PSCmdlet.ShouldProcess($functionName, "Execute test")) {
|
Write-Information "Executing test function: $functionName"
|
||||||
$auditResult = Invoke-TestFunction -FunctionFile $testFunction -DomainName $DomainName -ApprovedCloudStorageProviders $ApprovedCloudStorageProviders -ApprovedFederatedDomains $ApprovedFederatedDomains
|
$auditResult = Invoke-TestFunction -FunctionFile $testFunction -DomainName $DomainName -ApprovedCloudStorageProviders $ApprovedCloudStorageProviders -ApprovedFederatedDomains $ApprovedFederatedDomains
|
||||||
# Add the result to the collection
|
# Add the result to the collection
|
||||||
[void]$allAuditResults.Add($auditResult)
|
[void]$allAuditResults.Add($auditResult)
|
||||||
}
|
}
|
||||||
|
# Call the private function to calculate and display results
|
||||||
|
Measure-AuditResult -AllAuditResults $allAuditResults -FailedTests $script:FailedTests
|
||||||
|
# Return all collected audit results
|
||||||
|
# Define the test numbers to check
|
||||||
|
$TestNumbersToCheck = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
||||||
|
# Check for large details in the audit results
|
||||||
|
$exceedingTests = Get-ExceededLengthResultDetail -AuditResults $allAuditResults -TestNumbersToCheck $TestNumbersToCheck -ReturnExceedingTestsOnly -DetailsLengthLimit 30000
|
||||||
|
if ($exceedingTests.Count -gt 0) {
|
||||||
|
Write-Information "The following tests exceeded the details length limit: $($exceedingTests -join ', ')"
|
||||||
|
Write-Information "( Assuming the results were instantiated. Ex: `$object = invoke-M365SecurityAudit )`nUse the following command and adjust as necessary to view the full details of the test results:"
|
||||||
|
Write-Information "Export-M365SecurityAuditTable -ExportAllTests -AuditResults `$object -ExportPath `"C:\temp`" -ExportOriginalTests"
|
||||||
|
}
|
||||||
|
return $allAuditResults.ToArray() | Sort-Object -Property Rec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
# Log the error and add the test to the failed tests collection
|
# Log the error and add the test to the failed tests collection
|
||||||
Write-Verbose "Invoke-M365SecurityAudit: Failed to load test function $($_.Name): $_" -Verbose
|
throw "Failed to execute test function $($testFunction.Name): $_"
|
||||||
$script:FailedTests.Add([PSCustomObject]@{ Test = $_.Name; Error = $_ })
|
$script:FailedTests.Add([PSCustomObject]@{ Test = $_.Name; Error = $_ })
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
@@ -315,20 +285,6 @@ function Invoke-M365SecurityAudit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
End {
|
End {
|
||||||
if ($PSCmdlet.ShouldProcess("Measure and display audit results for $($totalTests) tests", "Measure")) {
|
|
||||||
# Call the private function to calculate and display results
|
|
||||||
Measure-AuditResult -AllAuditResults $allAuditResults -FailedTests $script:FailedTests
|
|
||||||
# Return all collected audit results
|
|
||||||
# Define the test numbers to check
|
|
||||||
$TestNumbersToCheck = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
|
||||||
# Check for large details in the audit results
|
|
||||||
$exceedingTests = Get-ExceededLengthResultDetail -AuditResults $allAuditResults -TestNumbersToCheck $TestNumbersToCheck -ReturnExceedingTestsOnly -DetailsLengthLimit 30000
|
|
||||||
if ($exceedingTests.Count -gt 0) {
|
|
||||||
Write-Information "The following tests exceeded the details length limit: $($exceedingTests -join ', ')" -InformationAction Continue
|
|
||||||
Write-Host "(Assuming the results were instantiated. Ex: `$object = invoke-M365SecurityAudit) Use the following command and adjust as neccesary to view the full details of the test results:" -ForegroundColor DarkCyan
|
|
||||||
Write-Host "Export-M365SecurityAuditTable -ExportAllTests -AuditResults `$object -ExportPath `"C:\temp`" -ExportOriginalTests" -ForegroundColor Green
|
|
||||||
}
|
|
||||||
return $allAuditResults.ToArray() | Sort-Object -Property Rec
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
64
source/Public/New-M365SecurityAuditAuthObject.ps1
Normal file
64
source/Public/New-M365SecurityAuditAuthObject.ps1
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Creates a new CISAuthenticationParameters object for Microsoft 365 authentication.
|
||||||
|
.DESCRIPTION
|
||||||
|
The New-M365SecurityAuditAuthObject function constructs a new CISAuthenticationParameters object
|
||||||
|
containing the necessary credentials and URLs for authenticating to various Microsoft 365 services.
|
||||||
|
It validates input parameters to ensure they conform to expected formats and length requirements.
|
||||||
|
An app registration in Azure AD with the required permissions to EXO, SPO, MSTeams and MgGraph is needed.
|
||||||
|
.PARAMETER ClientCertThumbPrint
|
||||||
|
The thumbprint of the client certificate used for authentication. It must be a 40-character hexadecimal string.
|
||||||
|
This certificate is used to authenticate the application in Azure AD.
|
||||||
|
.PARAMETER ClientId
|
||||||
|
The Client ID (Application ID) of the Azure AD application. It must be a valid GUID format.
|
||||||
|
.PARAMETER TenantId
|
||||||
|
The Tenant ID of the Azure AD directory. It must be a valid GUID format representing your Microsoft 365 tenant.
|
||||||
|
.PARAMETER OnMicrosoftUrl
|
||||||
|
The URL of your onmicrosoft.com domain. It should be in the format 'example.onmicrosoft.com'.
|
||||||
|
.PARAMETER SpAdminUrl
|
||||||
|
The SharePoint admin URL, which should end with '-admin.sharepoint.com'. This URL is used for connecting to SharePoint Online.
|
||||||
|
.INPUTS
|
||||||
|
None. You cannot pipe objects to this function.
|
||||||
|
.OUTPUTS
|
||||||
|
CISAuthenticationParameters
|
||||||
|
The function returns an instance of the CISAuthenticationParameters class containing the authentication details.
|
||||||
|
.EXAMPLE
|
||||||
|
PS> $authParams = New-M365SecurityAuditAuthObject -ClientCertThumbPrint "ABCDEF1234567890ABCDEF1234567890ABCDEF12" `
|
||||||
|
-ClientId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-TenantId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-OnMicrosoftUrl "yourcompany.onmicrosoft.com" `
|
||||||
|
-SpAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
|
Creates a new CISAuthenticationParameters object with the specified credentials and URLs, validating each parameter's format and length.
|
||||||
|
.NOTES
|
||||||
|
Requires PowerShell 7.0 or later.
|
||||||
|
#>
|
||||||
|
function New-M365SecurityAuditAuthObject {
|
||||||
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuthenticationParameters])]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true, HelpMessage = "The 40-character hexadecimal thumbprint of the client certificate.")]
|
||||||
|
[ValidatePattern("^[0-9a-fA-F]{40}$")] # Regex for a valid thumbprint format
|
||||||
|
[ValidateLength(40, 40)] # Enforce exact length
|
||||||
|
[string]$ClientCertThumbPrint,
|
||||||
|
[Parameter(Mandatory = $true, HelpMessage = "The Client ID (GUID format) of the Azure AD application.")]
|
||||||
|
[ValidatePattern("^[0-9a-fA-F\-]{36}$")] # Regex for a valid GUID
|
||||||
|
[string]$ClientId,
|
||||||
|
[Parameter(Mandatory = $true, HelpMessage = "The Tenant ID (GUID format) of the Azure AD directory.")]
|
||||||
|
[ValidatePattern("^[0-9a-fA-F\-]{36}$")] # Regex for a valid GUID
|
||||||
|
[string]$TenantId,
|
||||||
|
[Parameter(Mandatory = $true, HelpMessage = "The onmicrosoft.com domain URL (e.g., 'example.onmicrosoft.com').")]
|
||||||
|
[ValidatePattern("^[a-zA-Z0-9]+\.onmicrosoft\.com$")] # Regex for a valid onmicrosoft.com URL
|
||||||
|
[string]$OnMicrosoftUrl,
|
||||||
|
[Parameter(Mandatory = $true, HelpMessage = "The SharePoint admin URL ending with '-admin.sharepoint.com'.")]
|
||||||
|
[ValidatePattern("^https:\/\/[a-zA-Z0-9\-]+\-admin\.sharepoint\.com$")] # Regex for a valid SharePoint admin URL
|
||||||
|
[string]$SpAdminUrl
|
||||||
|
)
|
||||||
|
# Create and return the authentication parameters object
|
||||||
|
return [CISAuthenticationParameters]::new(
|
||||||
|
$ClientCertThumbPrint,
|
||||||
|
$ClientId,
|
||||||
|
$TenantId,
|
||||||
|
$OnMicrosoftUrl,
|
||||||
|
$SpAdminUrl
|
||||||
|
)
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,14 @@ EXAMPLES
|
|||||||
# Example 7: Granting Microsoft Graph permissions to the auditor
|
# Example 7: Granting Microsoft Graph permissions to the auditor
|
||||||
Grant-M365SecurityAuditConsent -UserPrincipalNameForConsent 'user@example.com'
|
Grant-M365SecurityAuditConsent -UserPrincipalNameForConsent 'user@example.com'
|
||||||
|
|
||||||
|
# Example 8: (PowerShell 7.x Only) Creating a new authentication object for the security audit for app-based authentication.
|
||||||
|
$authParams = New-M365SecurityAuditAuthObject -ClientCertThumbPrint "ABCDEF1234567890ABCDEF1234567890ABCDEF12" `
|
||||||
|
-ClientId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-TenantId "12345678-1234-1234-1234-123456789012" `
|
||||||
|
-OnMicrosoftUrl "yourcompany.onmicrosoft.com" `
|
||||||
|
-SpAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
|
Invoke-M365SecurityAudit -AuthParams $authParams -TenantAdminUrl "https://yourcompany-admin.sharepoint.com"
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
Ensure that you have the necessary permissions and administrative roles in
|
Ensure that you have the necessary permissions and administrative roles in
|
||||||
your Microsoft 365 environment to run these cmdlets. Proper configuration
|
your Microsoft 365 environment to run these cmdlets. Proper configuration
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
1,Test-AdministrativeAccountCompliance.ps1,1.1.1,Ensure Administrative accounts are separate and cloud-only,E3,L1,5.4,Restrict Administrator Privileges to Dedicated Administrator Accounts,TRUE,TRUE,TRUE,FALSE,Microsoft Graph
|
1,Test-AdministrativeAccountCompliance.ps1,1.1.1,Ensure Administrative accounts are separate and cloud-only,E3,L1,5.4,Restrict Administrator Privileges to Dedicated Administrator Accounts,TRUE,TRUE,TRUE,FALSE,Microsoft Graph
|
||||||
2,Test-GlobalAdminsCount.ps1,1.1.3,Ensure that between two and four global admins are designated,E3,L1,5.1,Establish and Maintain an Inventory of Accounts,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
|
2,Test-GlobalAdminsCount.ps1,1.1.3,Ensure that between two and four global admins are designated,E3,L1,5.1,Establish and Maintain an Inventory of Accounts,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
|
||||||
3,Test-ManagedApprovedPublicGroups.ps1,1.2.1,Ensure that only organizationally managed/approved public groups exist,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
|
3,Test-ManagedApprovedPublicGroups.ps1,1.2.1,Ensure that only organizationally managed/approved public groups exist,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
|
||||||
4,Test-BlockSharedMailboxSignIn.ps1,1.2.2,Ensure sign-in to shared mailboxes is blocked,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,AzureAD | EXO
|
4,Test-BlockSharedMailboxSignIn.ps1,1.2.2,Ensure sign-in to shared mailboxes is blocked,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO | Microsoft Graph
|
||||||
5,Test-PasswordNeverExpirePolicy.ps1,1.3.1,Ensure the 'Password expiration policy' is set to 'Set passwords to never expire',E3,L1,5.2,Use Unique Passwords,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
|
5,Test-PasswordNeverExpirePolicy.ps1,1.3.1,Ensure the 'Password expiration policy' is set to 'Set passwords to never expire',E3,L1,5.2,Use Unique Passwords,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
|
||||||
6,Test-ExternalSharingCalendars.ps1,1.3.3,Ensure 'External sharing' of calendars is not available,E3,L2,4.8,Uninstall or Disable Unnecessary Services on Enterprise Assets and Software,FALSE,TRUE,TRUE,TRUE,EXO
|
6,Test-ExternalSharingCalendars.ps1,1.3.3,Ensure 'External sharing' of calendars is not available,E3,L2,4.8,Uninstall or Disable Unnecessary Services on Enterprise Assets and Software,FALSE,TRUE,TRUE,TRUE,EXO
|
||||||
7,Test-CustomerLockbox.ps1,1.3.6,Ensure the customer lockbox feature is enabled,E5,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO
|
7,Test-CustomerLockbox.ps1,1.3.6,Ensure the customer lockbox feature is enabled,E5,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO
|
||||||
|
|
@@ -215,7 +215,7 @@ function Test-AntiPhishingPolicy {
|
|||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred during the test: $_"
|
Write-Error "An error occurred during the test $recnum`:: $_"
|
||||||
$auditResult = Get-TestError -LastError $_ -recnum $recnum
|
$auditResult = Get-TestError -LastError $_ -recnum $recnum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -58,9 +58,9 @@ function Test-BlockSharedMailboxSignIn {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
#>
|
#>
|
||||||
$users = Get-CISAadOutput -Rec $recnum
|
$users = Get-CISMgOutput -Rec $recnum
|
||||||
# Step: Retrieve details of shared mailboxes from Azure AD (Condition B: Pass/Fail)
|
# Step: Retrieve details of shared mailboxes from Azure AD (Condition B: Pass/Fail)
|
||||||
$sharedMailboxDetails = $users | Where-Object {$_.objectid -in $objectids}
|
$sharedMailboxDetails = $users | Where-Object {$_.id -in $objectids}
|
||||||
# Step: Identify enabled mailboxes (Condition B: Pass/Fail)
|
# Step: Identify enabled mailboxes (Condition B: Pass/Fail)
|
||||||
$enabledMailboxes = $sharedMailboxDetails | Where-Object { $_.AccountEnabled } | ForEach-Object { $_.DisplayName }
|
$enabledMailboxes = $sharedMailboxDetails | Where-Object { $_.AccountEnabled } | ForEach-Object { $_.DisplayName }
|
||||||
$allBlocked = $enabledMailboxes.Count -eq 0
|
$allBlocked = $enabledMailboxes.Count -eq 0
|
||||||
|
@@ -101,7 +101,7 @@ function Test-MailboxAuditingE3 {
|
|||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred during the test: $_"
|
Write-Error "An error occurred during the test $recnum`:: $_"
|
||||||
# Retrieve the description from the test definitions
|
# Retrieve the description from the test definitions
|
||||||
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
@@ -103,7 +103,7 @@ function Test-MailboxAuditingE5 {
|
|||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred during the test: $_"
|
Write-Error "An error occurred during the test $recnum`:: $_"
|
||||||
# Retrieve the description from the test definitions
|
# Retrieve the description from the test definitions
|
||||||
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
@@ -90,7 +90,7 @@ function Test-SafeAttachmentsPolicy {
|
|||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred during the test: $_"
|
Write-Error "An error occurred during the test $recnum`:: $_"
|
||||||
# Retrieve the description from the test definitions
|
# Retrieve the description from the test definitions
|
||||||
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
@@ -88,7 +88,7 @@ AllowSafeDocsOpen: $($_.AllowSafeDocsOpen)
|
|||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred during the test: $_"
|
Write-Error "An error occurred during the test $recnum`:: $_"
|
||||||
# Retrieve the description from the test definitions
|
# Retrieve the description from the test definitions
|
||||||
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
@@ -58,7 +58,7 @@ function Test-SafeLinksOfficeApps {
|
|||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred during the test: $_"
|
Write-Error "An error occurred during the test $recnum`:: $_"
|
||||||
# Retrieve the description from the test definitions
|
# Retrieve the description from the test definitions
|
||||||
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
@@ -108,7 +108,7 @@ function Test-SpamPolicyAdminNotify {
|
|||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred during the test: $_"
|
Write-Error "An error occurred during the test $recnum`:: $_"
|
||||||
$auditResult = Get-TestError -LastError $_ -recnum $recnum
|
$auditResult = Get-TestError -LastError $_ -recnum $recnum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user