Skip to content

Commit

Permalink
Merge pull request #518 from weyCC81/wey-TeamsConnect&Test
Browse files Browse the repository at this point in the history
Add Connection to Teams and the first Meeting Policies Tests
  • Loading branch information
merill authored Dec 10, 2024
2 parents dc3c1b1 + 82ecfa5 commit 80a678a
Show file tree
Hide file tree
Showing 11 changed files with 268 additions and 15 deletions.
45 changes: 40 additions & 5 deletions powershell/internal/ConvertTo-MtMaesterResults.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,39 @@ function ConvertTo-MtMaesterResult {
)

function GetTenantName() {
$org = Invoke-MtGraphRequest -RelativeUri 'organization'
return $org.DisplayName
if(Test-MtConnection Graph) {
$org = Invoke-MtGraphRequest -RelativeUri 'organization'
return $org.DisplayName
} elseif (Test-MtConnection Teams) {
$tenant = Get-CsTenant
return $tenant.DisplayName
} else {
return "TenantName (not connected to Graph)"
}
}

function GetTenantId() {
if(Test-MtConnection Graph) {
$mgContext = Get-MgContext
return $mgContext.TenantId
} elseif (Test-MtConnection Teams) {
$tenant = Get-CsTenant
return $tenant.TenantId
} else {
return "TenantId (not connected to Graph)"
}
}

function GetAccount() {
if(Test-MtConnection Graph) {
$mgContext = Get-MgContext
return $mgContext.Account
#} elseif (Test-MtConnection Teams) {
# $tenant = Get-CsTenant #ToValidate: N/A
# return $tenant.DisplayName
} else {
return "Account (not connected to Graph)"
}
}

function GetTestsSorted() {
Expand Down Expand Up @@ -42,11 +73,15 @@ function ConvertTo-MtMaesterResult {
return 'Unknown'
}

$mgContext = Get-MgContext
#if(Test-MtConnection Graph) { #ToValidate: Issue with -SkipGraphConnect
# $mgContext = Get-MgContext
#}

$tenantId = $mgContext.TenantId
#$tenantId = $mgContext.TenantId ?? "Tenant ID (not connected to Graph)"
$tenantId = GetTenantId
$tenantName = GetTenantName
$account = $mgContext.Account
#$account = $mgContext.Account ?? "Account (not connected to Graph)"
$account = GetAccount

$currentVersion = ((Get-Module -Name Maester).Version | Select-Object -Last 1).ToString()
$latestVersion = GetMaesterLatestVersion
Expand Down
1 change: 1 addition & 0 deletions powershell/internal/Get-MtSkippedReason.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ function Get-MtSkippedReason {
"NotConnectedAzure" { "Not connected to Azure. See [Connecting to Azure](https://maester.dev/docs/installation#optional-modules-and-permissions)"; break}
"NotConnectedExchange" { "Not connected to Exchange Online. See [Connecting to Exchange Online](https://maester.dev/docs/installation#optional-modules-and-permissions)"; break}
"NotConnectedSecurityCompliance" { "Not connected to Security & Compliance. See [Connecting to Security & Compliance](https://maester.dev/docs/installation#optional-modules-and-permissions)"; break}
"NotConnectedTeams" { "Not connected to Teams. See [Connecting to Teams](https://maester.dev/docs/installation#optional-modules-and-permissions)"; break} # Docs?
"NotConnectedGraph" { "Not connected to Graph. See [Connect-Maester](https://maester.dev/docs/commands/Connect-Maester#examples)"; break}
"NotDotGovDomain" { "This test is only for federal, executive branch, departments and agencies. To override use [Test-MtCisaDmarcAggregateCisa -Force](https://maester.dev/docs/commands/Test-MtCisaDmarcAggregateCisa)"; break}
"NotLicensedEntraIDP1" { "This test is for tenants that are licensed for Entra ID P1. See [Entra ID licensing](https://learn.microsoft.com/entra/fundamentals/licensing)"; break}
Expand Down
3 changes: 2 additions & 1 deletion powershell/internal/Update-MtMaesterTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ function Update-MtMaesterTests {
}

$message = "Run `Connect-Maester` to sign in and then run `Invoke-Maester` to start testing."
if (Get-MgContext) {
#if (Get-MgContext) { #ToAdjust: Issue with -SkipGraphConnect
if (Test-MtConnection Graph) {
$message = "Run Invoke-Maester to start testing."
}

Expand Down
2 changes: 1 addition & 1 deletion powershell/public/Add-MtTestResultDetail.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function Add-MtTestResultDetail {
[string] $TestName = $____Pester.CurrentTest.ExpandedName,

[Parameter(Mandatory = $false)]
[ValidateSet('NotConnectedAzure', 'NotConnectedExchange', 'NotConnectedGraph', 'NotDotGovDomain', 'NotLicensedEntraIDP1', 'NotConnectedSecurityCompliance',
[ValidateSet('NotConnectedAzure', 'NotConnectedExchange', 'NotConnectedGraph', 'NotDotGovDomain', 'NotLicensedEntraIDP1', 'NotConnectedSecurityCompliance', 'NotConnectedTeams',
'NotLicensedEntraIDP2', 'NotLicensedEntraIDGovernance', 'NotLicensedEntraWorkloadID', 'NotLicensedExoDlp', "LicensedEntraIDPremium", 'NotSupported', 'Custom',
'NotLicensedMdo','NotLicensedMdoP1', 'AdvAudit'
)]
Expand Down
25 changes: 23 additions & 2 deletions powershell/public/Connect-Maester.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,12 @@ function Connect-Maester {
[ValidateSet("O365China", "O365Default", "O365GermanyCloud", "O365USGovDoD", "O365USGovGCCHigh")]
[string]$ExchangeEnvironmentName = "O365Default",

# The Teams environment to connect to. Default is O365Default.
[ValidateSet("TeamsChina", "TeamsGCCH", "TeamsDOD")]
[string]$TeamsEnvironmentName = $null, #ToValidate: Don't use this parameter, this is the default.

# The services to connect to such as Azure and EXO. Default is Graph.
[ValidateSet("All", "Azure", "ExchangeOnline", "Graph", "SecurityCompliance")]
[ValidateSet("All", "Azure", "ExchangeOnline", "Graph", "SecurityCompliance","Teams")]
[string[]]$Service = "Graph"
)

Expand Down Expand Up @@ -129,7 +133,7 @@ function Connect-Maester {
if ($Service -contains "ExchangeOnline" -or $Service -contains "All") {
Write-Verbose "Connecting to Microsoft Exchage Online"
try {
if ( $UseDeviceCode -and $PSVersionTable.PSEdition -eq "Desktop" ) {
if ($UseDeviceCode -and $PSVersionTable.PSEdition -eq "Desktop") {
Write-Host "The Exchange Online module in Windows PowerShell does not support device code flow authentication." -ForegroundColor Red
Write-Host "💡Please use the Exchange Online module in PowerShell Core." -ForegroundColor Yellow
} elseif ( $UseDeviceCode ) {
Expand Down Expand Up @@ -182,4 +186,21 @@ function Connect-Maester {
}
}
}
if ($Service -contains "Teams") { #ToValidate: Preview
#if ($Service -contains "Teams" -or $Service -contains "All") {
Write-Verbose "Connecting to Microsoft Teams"
try {
if ($UseDeviceCode) {
Connect-MicrosoftTeams -UseDeviceAuthentication
} elseif ($TeamsEnvironmentName) {
Connect-MicrosoftTeams -TeamsEnvironmentName $TeamsEnvironmentName
} else {
Connect-MicrosoftTeams
#$null = Connect-MicrosoftTeams
}
} catch [Management.Automation.CommandNotFoundException] {
Write-Host "`nThe Teams PowerShell module is not installed. Please install the module using the following command. For more information see https://learn.microsoft.com/en-us/microsoftteams/teams-powershell-install" -ForegroundColor Red
Write-Host "`Install-Module MicrosoftTeams -Scope CurrentUser`n" -ForegroundColor Yellow
}
}
}
4 changes: 4 additions & 0 deletions powershell/public/Disconnect-Maester.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ function Disconnect-Maester {
Write-Verbose -Message "Disconnecting from Microsoft Exchange Online."
Disconnect-ExchangeOnline
}
if($__MtSession.Connections -contains "Teams" -or $__MtSession.Connections -contains "All"){
Write-Verbose -Message "Disconnecting from Microsoft Teams."
Disconnect-MicrosoftTeams
}
}
14 changes: 13 additions & 1 deletion powershell/public/core/Test-MtConnection.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function Test-MtConnection {
[CmdletBinding()]
param(
# Checks if the current session is connected to the specified service
[ValidateSet("All", "Azure", "ExchangeOnline", "Graph", "SecurityCompliance")]
[ValidateSet("All", "Azure", "ExchangeOnline", "Graph", "SecurityCompliance","Teams")]
[Parameter(Position = 0, Mandatory = $false)]
[string[]]$Service = "Graph"
)
Expand Down Expand Up @@ -76,5 +76,17 @@ function Test-MtConnection {
if (!$isConnected) { $connectionState = $false }
}

if ($Service -contains "Teams") { #ToValidate: Preview
#if ($Service -contains "Teams" -or $Service -contains "All") {
$isConnected = $false
try {
$isConnected = $null -ne (Get-CsTenant -ErrorAction SilentlyContinue)
} catch {
Write-Debug "Teams: $false"
}
Write-Verbose "Teams: $isConnected"
if (!$isConnected) { $connectionState = $false }
}

Write-Output $connectionState
}
149 changes: 149 additions & 0 deletions tests/Maester/Teams/Test-TeamsMeeting.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
BeforeDiscovery {
try {

$TeamsMeetingPolicy = Get-CsTeamsMeetingPolicy
Write-Verbose "Found $($TeamsMeetingPolicy.Count) Teams Meeting policies"
$TeamsMeetingPolicyGlobal = $TeamsMeetingPolicy | Where-Object { $_.Identity -eq "Global" }
Write-Verbose "Filtered $( $TeamsMeetingPolicyGlobal.Count) Global Teams Meeting policy"

} catch {
Write-Verbose "Session is not established, run Connect-MicrosoftTeams before requesting access token"
}
}

Describe "Teams Meeting policies" -Tag "Maester", "Teams", "MeetingPolicy" {


It "Configure which users are allowed to present in Teams meetings" -Tag "AllowParticipantGiveRequestControl" {

$portalLink_MeetingPolicy = "https://admin.teams.microsoft.com/policies/meetings"

if (!(Test-MtConnection Teams)) {
Add-MtTestResultDetail -SkippedBecause NotConnectedTeams
return $null
}

$result = $TeamsMeetingPolicyGlobal.AllowParticipantGiveRequestControl

if ($result -eq $false) {
$testResultMarkdown = "Well done. AllowParticipantGiveRequestControl is $($result)`n`n"
} else {
$testResultMarkdown = "AllowParticipantGiveRequestControl in [Meeting policies]($portalLink_MeetingPolicy) should be False and is $($result) `n`n"
}
$testDetailsMarkdown = "Only allow users with presenter rights to share content during meetings. Restricting who can present limits meeting disruptions and reduces the risk of unwanted or inappropriate content being shared."
Add-MtTestResultDetail -Description $testDetailsMarkdown -Result $testResultMarkdown

$result | Should -Be $false -Because "AllowParticipantGiveRequestControl should be False"
}

It "Only invited users should be automatically admitted to Teams meetings" -Tag "AutoAdmittedUsers" {
#($TeamsMeetingPolicyGlobal.AutoAdmittedUsers -eq "InvitedUsers")

$portalLink_MeetingPolicy = "https://admin.teams.microsoft.com/policies/meetings"

if (!(Test-MtConnection Teams)) {
Add-MtTestResultDetail -SkippedBecause NotConnectedTeams
return $null
}

$result = $TeamsMeetingPolicyGlobal.AutoAdmittedUsers

if ($result -eq "InvitedUsers") {
$testResultMarkdown = "Well done. AutoAdmittedUsers is $($result)`n`n"
} else {
$testResultMarkdown = "AutoAdmittedUsers in [Meeting policies]($portalLink_MeetingPolicy) should be InvitedUsers and is $($result) `n`n"
}
$testDetailsMarkdown = "Users who aren’t invited to a meeting shouldn’t be let in automatically, because it increases the risk of data leaks, inappropriate content being shared, or malicious actors joining. If only invited users are automatically admitted, then users who weren’t invited will be sent to a meeting lobby. The host can then decide whether or not to let them in."
Add-MtTestResultDetail -Description $testDetailsMarkdown -Result $testResultMarkdown

$result | Should -Be "InvitedUsers" -Because "AutoAdmittedUsers should be InvitedUsers"
}

It "Restrict anonymous users from joining meetings" -Tag "AllowAnonymousUsersToJoinMeeting" {

$portalLink_MeetingPolicy = "https://admin.teams.microsoft.com/policies/meetings"

if (!(Test-MtConnection Teams)) {
Add-MtTestResultDetail -SkippedBecause NotConnectedTeams
return $null
}

$result = $TeamsMeetingPolicyGlobal.AllowAnonymousUsersToJoinMeeting

if ($result -eq $false) {
$testResultMarkdown = "Well done. AllowAnonymousUsersToJoinMeeting is $($result)`n`n"
} else {
$testResultMarkdown = "AllowAnonymousUsersToJoinMeeting in [Meeting policies]($portalLink_MeetingPolicy) should be False and is $($result) `n`n"
}
$testDetailsMarkdown = "By restricting anonymous users from joining Microsoft Teams meetings, you have full control over meeting access. Anonymous users may not be from your organization and could have joined for malicious purposes, such as gaining information about your organization through conversations."
Add-MtTestResultDetail -Description $testDetailsMarkdown -Result $testResultMarkdown

$result | Should -Be $false -Because "AllowAnonymousUsersToJoinMeeting should be False"
}

It "Restrict anonymous users from starting Teams meetings" -Tag "AllowAnonymousUsersToStartMeeting" {

$portalLink_MeetingPolicy = "https://admin.teams.microsoft.com/policies/meetings"

if (!(Test-MtConnection Teams)) {
Add-MtTestResultDetail -SkippedBecause NotConnectedTeams
return $null
}

$result = $TeamsMeetingPolicyGlobal.AllowAnonymousUsersToStartMeeting

if ($result -eq $false) {
$testResultMarkdown = "Well done. AllowAnonymousUsersToStartMeeting is $($result)`n`n"
} else {
$testResultMarkdown = "AllowAnonymousUsersToStartMeeting in [Meeting policies]($portalLink_MeetingPolicy) should be False and is $($result) `n`n"
}
$testDetailsMarkdown = "If anonymous users are allowed to start meetings, they can admit any users from the lobbies, authenticated or otherwise. Anonymous users haven’t been authenticated, which can increase the risk of data leakage."
Add-MtTestResultDetail -Description $testDetailsMarkdown -Result $testResultMarkdown

$result | Should -Be $false -Because "AllowAnonymousUsersToStartMeeting should be False"
}

It "Limit external participants from having control in a Teams meeting" -Tag "AllowExternalParticipantGiveRequestControl" {

$portalLink_MeetingPolicy = "https://admin.teams.microsoft.com/policies/meetings"

if (!(Test-MtConnection Teams)) {
Add-MtTestResultDetail -SkippedBecause NotConnectedTeams
return $null
}

$result = $TeamsMeetingPolicyGlobal.AllowExternalParticipantGiveRequestControl

if ($result -eq $false) {
$testResultMarkdown = "Well done. AllowExternalParticipantGiveRequestControl is $($result)`n`n"
} else {
$testResultMarkdown = "AllowExternalParticipantGiveRequestControl in [Meeting policies]($portalLink_MeetingPolicy) should be False and is $($result) `n`n"
}
$testDetailsMarkdown = "External participants are users that are outside your organization. Limiting their permission to share content, add new users, and more protects your organization’s information from data leaks, inappropriate content being shared, or malicious actors joining the meeting."
Add-MtTestResultDetail -Description $testDetailsMarkdown -Result $testResultMarkdown

$result | Should -Be $false -Because "AllowExternalParticipantGiveRequestControl should be False"
}

It "Restrict dial-in users from bypassing a meeting lobby " -Tag "AllowPSTNUsersToBypassLobby" {

$portalLink_MeetingPolicy = "https://admin.teams.microsoft.com/policies/meetings"

if (!(Test-MtConnection Teams)) {
Add-MtTestResultDetail -SkippedBecause NotConnectedTeams
return $null
}

$result = $TeamsMeetingPolicyGlobal.AllowPSTNUsersToBypassLobby

if ($result -eq $false) {
$testResultMarkdown = "Well done. AllowPSTNUsersToBypassLobby is $($result)`n`n"
} else {
$testResultMarkdown = "AllowPSTNUsersToBypassLobby in [Meeting policies]($portalLink_MeetingPolicy) should be False and is $($result) `n`n"
}
$testDetailsMarkdown = "Dial-in users aren’t authenticated though the Teams app. Increase the security of your meetings by preventing these unknown users from bypassing the lobby and immediately joining the meeting."
Add-MtTestResultDetail -Description $testDetailsMarkdown -Result $testResultMarkdown

$result | Should -Be $false -Because "AllowPSTNUsersToBypassLobby should be False"
}
}
17 changes: 17 additions & 0 deletions website/docs/commands/Connect-Maester.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,23 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -TeamsEnvironmentName
The Teams environment to connect to.
Default is $null
```yaml
Type: String
Parameter Sets: (All)
Aliases:

Required: False
Position: 3
Default value: $null
Accept pipeline input: False
Accept wildcard characters: False
```
### -Service
The services to connect to such as Azure and EXO.
Expand Down
15 changes: 14 additions & 1 deletion website/docs/connect-maester/connect-maester-advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,17 @@ The Microsoft Exchange Online and Security & Compliance PowerShell Modules provi
Connect-ExchangeOnline -Certificate $cert -AppID $applicationId -Organization $moera -ShowBanner:$false
Connect-IPPSSession -Certificate $cert -AppID $applicationId -Organization $moera -ShowBanner:$false
```
```

### Microsoft Teams PowerShell Module

The Microsoft Teams PowerShell Module supports both interactive and non-interactive [authentication methods](https://learn.microsoft.com/powershell/module/teams/connect-microsoftteams?view=teams-ps). For interactive sessions, you can use the standard login prompt. For non-interactive use, such as in automation scenarios, service principal authentication is recommended.

```powershell
# Interactive
Connect-MicrosoftTeams
# Non-Interactive (Service Principal)
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\exampleCert.pfx",$password)
Connect-MicrosoftTeams -Certificate $cert -ApplicationId $applicationId -TenantId $tenantId
```
8 changes: 4 additions & 4 deletions website/docs/connect-maester/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ The `-DeviceCode` switch allows you to sign in using the device code flow. This
Connect-Maester -UseDeviceCode
```

### Connect to Azure and Exchange Online
### Connect to Azure, Exchange Online and Teams

`Connect-Maester` also provides options to connect to Azure and Exchange Online for running tests that use the Azure PowerShell and Exchange Online PowerShell modules.
`Connect-Maester` also provides options to connect to Azure, Exchange Online adn Teams for running tests that use the Azure PowerShell, Exchange Online PowerShell or Teams PowerShell modules.

The `-All` switch can be used to connect to all the services used by the Maester tests. This includes Microsoft Graph, Azure, Exchange Online and Security Compliance.
The `-All` switch can be used to connect to all the services used by the Maester tests. This includes Microsoft Graph, Azure, Exchange Online, Security Compliance and Microsoft Teams.

```powershell
Connect-Maester -Service All
Expand All @@ -91,7 +91,7 @@ Connect-Maester -Service All
If you need to connect to just a subset of the services you can specifiy them using the `-Service` parameter.

```powershell
Connect-Maester -Service Azure,Graph
Connect-Maester -Service Azure,Graph,Teams
```

### Connect to US Government, US DoD, China and Germany and other clouds
Expand Down

0 comments on commit 80a678a

Please sign in to comment.