diff --git a/.gitignore b/.gitignore index 2a85f2cf..23292be6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ *.user *.userosscache *.sln.docstates - +.test # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/action.yml b/action.yml index f4e0c6b3..038dceb2 100644 --- a/action.yml +++ b/action.yml @@ -53,6 +53,16 @@ inputs: description: "Installs the preview version, allowing access to new cmdlets." required: false default: false + include_exchange: + type: boolean + description: "Include Exchange Online tests in the test run." + required: false + default: true + include_teams: + type: boolean + description: "Include Team tests in the test run." + required: false + default: true disable_telemetry: type: boolean description: "If set, telemetry information will not be logged." @@ -68,6 +78,7 @@ runs: client-id: ${{ inputs.client_id }} tenant-id: ${{ inputs.tenant_id }} allow-no-subscriptions: true + enable-AzPSSession: true - name: Set current date as env variable shell: bash @@ -89,77 +100,20 @@ runs: uses: azure/powershell@v2 with: inlineScript: | - # Get Token - $token = az account get-access-token --resource-type ms-graph - - # Connect to Microsoft Graph - $accessToken = ($token | ConvertFrom-Json).accessToken | ConvertTo-SecureString -AsPlainText -Force - Connect-MgGraph -AccessToken $accessToken -NoWelcome - - # Install Maester - if ( '${{ inputs.install_prerelease}}' -eq $true ){ - Write-Host "Installing prerelease version" - Install-Module Maester -AllowPrerelease -Force - } else { - Write-Host "Installing latest version" - Install-Module Maester -Force - } - - - # Configure test results - $PesterConfiguration = New-PesterConfiguration - $PesterConfiguration.Output.Verbosity = '${{ inputs.pester_verbosity }}' - Write-Host "Pester verbosity level set to: $($PesterConfiguration.Output.Verbosity.Value)" - - $MaesterParameters = @{ - Path = '${{ github.workspace }}' - PesterConfiguration = $PesterConfiguration - OutputFolder = 'test-results' - OutputFolderFileName = 'test-results' - PassThru = $true - } - - # Check if test tags are provided - if ( [string]::IsNullOrWhiteSpace( '${{ inputs.include_tags }}' ) -eq $false ) { - $TestTags = '${{ inputs.include_tags }}' -split ',' - $MaesterParameters.Add( 'Tag', $TestTags ) - Write-Host "Running tests with tags: $TestTags" - } - - # Check if exclude test tags are provided - if ( [string]::IsNullOrWhiteSpace( '${{ inputs.exclude_tags }}' ) -eq $false ) { - $ExcludeTestTags = '${{ inputs.exclude_tags }}' -split ',' - $MaesterParameters.Add( 'ExcludeTag', $ExcludeTestTags ) - Write-Host "Excluding tests with tags: $ExcludeTestTags" - } - - # Check if mail recipients and mail userid are provided - if ( [string]::IsNullOrWhiteSpace( '${{ inputs.mail_userid }}' ) -eq $false ) { - if ( [string]::IsNullOrWhiteSpace( '${{ inputs.mail_recipients }}' ) -eq $false ) { - # Add mail parameters - $MaesterParameters.Add( 'MailUserId', '${{ inputs.mail_userid }}' ) - $Recipients = '${{ inputs.mail_recipients }}' -split ',' - $MaesterParameters.Add( 'MailRecipient', $Recipients ) - $MaesterParameters.Add( 'MailTestResultsUri', '${{ inputs.mail_testresultsuri }}' ) - Write-Host "Mail notification will be sent to: $Recipients" - } else { - Write-Warning "Mail recipients are not provided. Skipping mail notification." - } - } - - # Check if disable telemetry is provided - if ( [string]::IsNullOrWhiteSpace( '${{ inputs.disable_telemetry}}' ) -eq $true ) { - $MaesterParameters.Add( 'DisableTelemetry', $true ) - } - - # Run Maester tests - $results = Invoke-Maester @MaesterParameters - - if('${{ inputs.step_summary }}' -ne $false) { - # Add step summary - $summary = Get-Content test-results/test-results.md - Add-Content -Path $env:GITHUB_STEP_SUMMARY -Value $summary - } + ${{ github.action_path }}\action\Run-Maester.ps1 -TenantId '${{ inputs.tenant_id}}' ` + -ClientId '${{ inputs.client_id }}' ` + -Path '${{ github.workspace }}' ` + -MailRecipients '${{ inputs.mail_recipients }}' ` + -MailUser '${{ inputs.mail_userid }}' ` + -TestResultURI '${{ inputs.mail_testresultsuri }}' ` + -IncludeTags '${{ inputs.include_tags }}' ` + -ExcludeTags '${{ inputs.exclude_tags }}' ` + -PesterVerbosity '${{ inputs.pester_verbosity }}' ` + -GitHubStepSummary ('${{ inputs.step_summary }}' -eq 'true') ` + -Preview ('${{ inputs.install_prerelease }}' -eq 'true') ` + -IncludeExchange ('${{ inputs.include_exchange }}' -eq 'true') ` + -IncludeTeams ('${{ inputs.include_teams }}' -eq 'true') ` + -DisableTelemetry ('${{ inputs.disable_telemetry}}' -eq 'true') azPSVersion: "latest" - name: Archive Maester Html Report diff --git a/action/README.md b/action/README.md new file mode 100644 index 00000000..56a3e156 --- /dev/null +++ b/action/README.md @@ -0,0 +1,108 @@ +# Maester Action Script + +This PowerShell script is used to monitor your tenant's security configuration using Maester, a PowerShell-based test automation framework. + +## Parameters + +### Required Parameters + +- **TenantId** + - The Entra Tenant Id. + - Type: `string` + - Mandatory: `true` + +- **ClientId** + - The Client Id of the Service Principal. + - Type: `string` + - Mandatory: `true` + +- **Path** + - The path for the files and Pester tests. + - Type: `string` + - Mandatory: `true` + +### Optional Parameters + +- **PesterVerbosity** + - The Pester verbosity level. + - Type: `string` + - Mandatory: `false` + - Default: `None` + - Allowed Values: `None`, `Normal`, `Detailed`, `Diagnostic` + +- **MailUser** + - The mail user id. + - Type: `string` + - Mandatory: `false` + - Default: `""` + +- **MailTo** + - The mail recipients separated by comma. + - Type: `string` + - Mandatory: `false` + - Default: `""` + +- **TestResultURI** + - The test result URI. + - Type: `string` + - Mandatory: `false` + - Default: `""` + +- **IncludeTags** + - The tags to include in the tests. + - Type: `string` + - Mandatory: `false` + - Default: `""` + +- **ExcludeTags** + - The tags to exclude in the tests. + - Type: `string` + - Mandatory: `false` + - Default: `""` + +- **IncludeExchange** + - Include Exchange Online tests. + - Type: `bool` + - Mandatory: `false` + - Default: `$true` + +- **IncludeTeams** + - Include Teams tests. + - Type: `bool` + - Mandatory: `false` + - Default: `$true` + +- **Preview** + - Install preview version of Maester. + - Type: `bool` + - Mandatory: `false` + - Default: `$false` + +- **DisableTelemetry** + - Disable telemetry. + - Type: `bool` + - Mandatory: `false` + - Default: `$false` + +- **GitHubStepSummary** + - Add test results to GitHub step summary. + - Type: `bool` + - Mandatory: `false` + - Default: `$false` + +## Usage + +```powershell +.\Run-Maester.ps1 -TenantId "your-tenant-id" -ClientId "your-client-id" -Path "path-to-tests" -PesterVerbosity "Normal" -MailUser "user@example.com" -MailTo "recipient1@example.com,recipient2@example.com" -TestResultURI "http://example.com/results" -IncludeTags "tag1,tag2" -ExcludeTags "tag3" -IncludeExchange $true -IncludeTeams $true -Preview $false -DisableTelemetry $false -GitHubStepSummary $true +``` + +## Example +```powershell +.\Run-Maester.ps1 -TenantId "12345678-1234-1234-1234-123456789012" -ClientId "87654321-4321-4321-4321-210987654321" -Path "./tests" -PesterVerbosity "Detailed" -MailUser "admin@example.com" -MailTo "user1@example.com,user2@example.com" -TestResultURI "http://example.com/results" -IncludeTags "security,compliance" -ExcludeTags "performance" -IncludeExchange $true -IncludeTeams $true -Preview $true -DisableTelemetry $true -GitHubStepSummary $true +``` + +## Notes + +- Ensure you have the necessary permissions and modules installed before running the script. +- The script connects to Microsoft Graph and may require additional authentication steps. +- The script can be customized further by modifying the parameters and their default values. diff --git a/action/Run-Maester.ps1 b/action/Run-Maester.ps1 new file mode 100644 index 00000000..1a83071c --- /dev/null +++ b/action/Run-Maester.ps1 @@ -0,0 +1,144 @@ +param ( + [Parameter(Mandatory=$true, HelpMessage="The Entra Tenant Id")] + [string]$TenantId, + + [Parameter(Mandatory=$true, HelpMessage="The Client Id of the Service Principal")] + [string]$ClientId, + + [Parameter(Mandatory=$true, HelpMessage="The path for the files and pester tests")] + [string]$Path, + + [Parameter(Mandatory=$false, HelpMessage="The Pester verbosity level")] + [ValidateSet("None", "Normal", "Detailed", "Diagnostic")] + [string]$PesterVerbosity = "None", + + [Parameter(Mandatory=$false, HelpMessage="The mail user id")] + [string]$MailUser = "", + + [Parameter(Mandatory=$false, HelpMessage="The mail recipients seperated by comma")] + [string]$MailRecipients = "", + + [Parameter(Mandatory=$false, HelpMessage="The test result uri")] + [string]$TestResultURI = "", + + [Parameter(Mandatory=$false, HelpMessage="The tags to include in the tests")] + [string]$IncludeTags = "", + + [Parameter(Mandatory=$false, HelpMessage="The tags to exclude in the tests")] + [string]$ExcludeTags = "", + + [Parameter(Mandatory=$false, HelpMessage="Include Exchange Online tests")] + [bool]$IncludeExchange = $true, + + [Parameter(Mandatory=$false, HelpMessage="Include Teams tests")] + [bool]$IncludeTeams = $true, + + [Parameter(Mandatory=$false, HelpMessage="Install preview version of Maester")] + [bool]$Preview = $false, + + [Parameter(Mandatory=$false, HelpMessage="Disable telemetry")] + [bool]$DisableTelemetry = $false, + + [Parameter(Mandatory=$false, HelpMessage="Add test results to GitHub step summary")] + [bool]$GitHubStepSummary = $false +) + +BEGIN{ + Write-Host "Starting Maester tests" +} +PROCESS{ + $graphToken = Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com" -AsSecureString + + # Connect to Microsoft Graph with the token as secure string + Connect-MgGraph -AccessToken $graphToken.Token -NoWelcome + + # Check if we need to connect to Exchange Online + if ($IncludeExchange) { + Install-Module ExchangeOnlineManagement -Force + Import-Module ExchangeOnlineManagement + + $outlookToken = Get-AzAccessToken -ResourceUrl 'https://outlook.office365.com' + Connect-ExchangeOnline -AccessToken $outlookToken.Token -AppId $ClientId -Organization $TenantId -ShowBanner:$false + }else{ + Write-Host "Exchange Online tests will be skipped." + } + + # Check if we need to connect to Exchange Online + if ($IncludeTeams) { + Install-Module MicrosoftTeams -Force + Import-Module MicrosoftTeams + + $teamsToken = Get-AzAccessToken -ResourceUrl "48ac35b8-9aa8-4d74-927d-1f4a14a0b239" + + $regularGraphToken = ConvertFrom-SecureString -SecureString $graphToken.Token -AsPlainText + $tokens = @($regularGraphToken, $teamsToken.Token) + Connect-MicrosoftTeams -AccessTokens $tokens -Verbose + }else{ + Write-Host "Teams tests will be skipped." + } + + # Install Maester + if ($Preview){ + Install-Module Maester -AllowPrerelease -Force + } else { + Install-Module Maester -Force + } + + # Configure test results + $PesterConfiguration = New-PesterConfiguration + $PesterConfiguration.Output.Verbosity = $PesterVerbosity + Write-Host "Pester verbosity level set to: $($PesterConfiguration.Output.Verbosity.Value)" + + $MaesterParameters = @{ + Path = $Path + PesterConfiguration = $PesterConfiguration + OutputFolder = 'test-results' + OutputFolderFileName = 'test-results' + PassThru = $true + } + + # Check if test tags are provided + if ( [string]::IsNullOrWhiteSpace($IncludeTags) -eq $false ) { + $TestTags = $IncludeTags -split ',' + $MaesterParameters.Add( 'Tag', $TestTags ) + Write-Host "Running tests with tags: $TestTags" + } + + # Check if exclude test tags are provided + if ( [string]::IsNullOrWhiteSpace($ExcludeTags) -eq $false ) { + $ExcludeTestTags = $ExcludeTags -split ',' + $MaesterParameters.Add( 'ExcludeTag', $ExcludeTestTags ) + Write-Host "Excluding tests with tags: $ExcludeTestTags" + } + + # Check if mail recipients and mail userid are provided + if ( [string]::IsNullOrWhiteSpace($MailUser) -eq $false ) { + if ( [string]::IsNullOrWhiteSpace( '${{ inputs.mail_recipients }}' ) -eq $false ) { + # Add mail parameters + $MaesterParameters.Add( 'MailUserId', $MailUser ) + $Recipients = $MailRecipients -split ',' + $MaesterParameters.Add( 'MailRecipient', $Recipients ) + $MaesterParameters.Add( 'MailTestResultsUri', $TestResultURI ) + Write-Host "Mail notification will be sent to: $Recipients" + } else { + Write-Warning "Mail recipients are not provided. Skipping mail notification." + } + } + + # Check if disable telemetry is provided + if ($DisableTelemetry ) { + $MaesterParameters.Add( 'DisableTelemetry', $true ) + } + + # Run Maester tests + $results = Invoke-Maester @MaesterParameters + + if($GitHubStepSummary) { + # Add step summary + $summary = Get-Content test-results/test-results.md + Add-Content -Path $env:GITHUB_STEP_SUMMARY -Value $summary + } +} +END{ + Write-Host "Maester tests completed!" +} \ No newline at end of file