Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/teams compliance recording policy #3754

Merged
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
18e8ddf
fix ComplianceRecordingApplications
sandrola Sep 26, 2023
691e5d6
wip
sandrola Sep 26, 2023
d9865a3
Merge branch 'microsoft:Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Oct 3, 2023
b82c1d7
Merge branch 'microsoft:Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Oct 4, 2023
1f46e89
Fixes MSFT_TeamsComplianceRecordingPolicy attribute not exported corr…
sandrola Oct 4, 2023
0d08b7d
Add Tests
sandrola Oct 4, 2023
5556bfe
Add Example
sandrola Oct 4, 2023
4aedebb
Add Entry in ChangeLog
sandrola Oct 4, 2023
106fc70
Merge branch 'Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Oct 6, 2023
472f599
Merge branch 'Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Oct 11, 2023
e61ecc7
Merge branch 'microsoft:Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Oct 11, 2023
5f6a23d
Fix example file
sandrola Oct 11, 2023
8e59d4e
Correct formatting
sandrola Nov 17, 2023
24a5053
minor typo
sandrola Nov 17, 2023
a053480
Merge branch 'Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Mar 18, 2024
5f4763b
Update tests
sandrola Mar 18, 2024
d719425
Merge branch 'Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Mar 28, 2024
4a10387
Merge branch 'Dev' into fix/TeamsComplianceRecordingPolicy
sandrola May 15, 2024
4d101f5
Merge branch 'fix/TeamsComplianceRecordingPolicy' of https://github.c…
sandrola May 15, 2024
efff7ad
Merge branch 'Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Sep 30, 2024
71034c6
Merge branch 'Dev' into fix/TeamsComplianceRecordingPolicy
sandrola Oct 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# UNRELEASED

* TeamsComplianceREcordingPolicy
NikCharlebois marked this conversation as resolved.
Show resolved Hide resolved
andikrueger marked this conversation as resolved.
Show resolved Hide resolved
NikCharlebois marked this conversation as resolved.
Show resolved Hide resolved
* FIXES [[#3712](https://github.com/microsoft/Microsoft365DSC/issues/3712)]
* EXODistributionGroup
* Fixes the export of group membership to use Identity.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function Get-TargetResource
$Identity,

[Parameter()]
[System.String[]]
[Microsoft.Management.Infrastructure.CimInstance[]]
$ComplianceRecordingApplications,

[Parameter()]
Expand Down Expand Up @@ -75,10 +75,34 @@ function Get-TargetResource
return $nullResult
}

if($instance.ComplianceRecordingApplications.Count -gt 0){
$ComplexComplianceRecordingApplications = @()
foreach($CurrentComplianceRecordingApplications in $instance.ComplianceRecordingApplications){
$MyComplianceRecordingApplications = @{}
$ComplianceRecordingPairedApplications = @()
if($CurrentComplianceRecordingApplications.ComplianceRecordingPairedApplications.Count -gt 0){
foreach($CurrentComplianceRecordingPairedApplications in $CurrentComplianceRecordingApplications.ComplianceRecordingPairedApplications){
$ComplianceRecordingPairedApplications += $CurrentComplianceRecordingApplications.ComplianceRecordingPairedApplications.Id
}
}
$MyComplianceRecordingApplications.Add('ComplianceRecordingPairedApplications', $ComplianceRecordingPairedApplications)
$MyComplianceRecordingApplications.Add('Id', $CurrentComplianceRecordingApplications.Id)
$MyComplianceRecordingApplications.Add('RequiredBeforeMeetingJoin', $CurrentComplianceRecordingApplications.RequiredBeforeMeetingJoin)
$MyComplianceRecordingApplications.Add('RequiredBeforeCallEstablishment', $CurrentComplianceRecordingApplications.RequiredBeforeCallEstablishment)
$MyComplianceRecordingApplications.Add('RequiredDuringMeeting', $CurrentComplianceRecordingApplications.RequiredDuringMeeting)
$MyComplianceRecordingApplications.Add('RequiredDuringCall', $CurrentComplianceRecordingApplications.RequiredDuringCall)
$MyComplianceRecordingApplications.Add('ConcurrentInvitationCount', $CurrentComplianceRecordingApplications.ConcurrentInvitationCount)

if ($MyComplianceRecordingApplications.values.Where({$null -ne $_}).count -gt 0){
$ComplexComplianceRecordingApplications += $MyComplianceRecordingApplications
}
}
}

Write-Verbose -Message "Found an instance with Identity {$Identity}"
$results = @{
Identity = $instance.Identity
ComplianceRecordingApplications = $instance.ComplianceRecordingApplications
ComplianceRecordingApplications = $ComplexComplianceRecordingApplications
Description = $instance.Description
DisableComplianceRecordingAudioNotificationForCalls = $instance.DisableComplianceRecordingAudioNotificationForCalls
Enabled = $instance.Enabled
Expand Down Expand Up @@ -113,7 +137,7 @@ function Set-TargetResource
$Identity,

[Parameter()]
[System.String[]]
[Microsoft.Management.Infrastructure.CimInstance[]]
$ComplianceRecordingApplications,

[Parameter()]
Expand Down Expand Up @@ -190,13 +214,55 @@ function Set-TargetResource
{
if ($null -ne $CreateParameters.$key -and $CreateParameters.$key.GetType().Name -like '*cimInstance*')
{
$keyName = $key.substring(0, 1).ToLower() + $key.substring(1, $key.length - 1)
$keyValue = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $CreateParameters.$key
$CreateParameters.Remove($key) | Out-Null
$CreateParameters.Add($keyName, $keyValue)
}
}
Write-Verbose -Message "Creating {$Identity} with Parameters:`r`n$(Convert-M365DscHashtableToString -Hashtable $CreateParameters)"
New-CsTeamsComplianceRecordingPolicy @CreateParameters | Out-Null

if($ComplianceRecordingApplications.Count -gt 0){
sandrola marked this conversation as resolved.
Show resolved Hide resolved
foreach($CurrentComplianceRecordingApplications in $ComplianceRecordingApplications){
$Instance = $CurrentComplianceRecordingApplications.Id
$RequiredBeforeMeetingJoin = $CurrentComplianceRecordingApplications.RequiredBeforeMeetingJoin
$RequiredBeforeCallEstablishment = $CurrentComplianceRecordingApplications.RequiredBeforeCallEstablishment
$RequiredDuringMeeting = $CurrentComplianceRecordingApplications.RequiredDuringMeeting
$RequiredDuringCall = $CurrentComplianceRecordingApplications.RequiredDuringCall
$ConcurrentInvitationCount = $CurrentComplianceRecordingApplications.ConcurrentInvitationCount

$CsTeamsComplianceRecordingApplication = Get-CsTeamsComplianceRecordingApplication -Identity $CsTeamsComplianceRecordingApplicationIdentity -ErrorAction SilentlyContinue
if($null -eq $CsTeamsComplianceRecordingApplication){
New-CsTeamsComplianceRecordingApplication `
-RequiredBeforeMeetingJoin $RequiredBeforeMeetingJoin `
-RequiredBeforeCallEstablishment $RequiredBeforeCallEstablishment `
-RequiredDuringMeeting $RequiredDuringMeeting `
-RequiredDuringCall $RequiredDuringCall `
-ConcurrentInvitationCount $ConcurrentInvitationCount `
-Parent $Identity -Id $Instance
}
else{
Set-CsTeamsComplianceRecordingApplication `
-Identity $CsTeamsComplianceRecordingApplicationIdentity `
-RequiredBeforeMeetingJoin $RequiredBeforeMeetingJoin `
-RequiredBeforeCallEstablishment $RequiredBeforeCallEstablishment `
-RequiredDuringMeeting $RequiredDuringMeeting `
-RequiredDuringCall $RequiredDuringCall `
-ConcurrentInvitationCount $ConcurrentInvitationCount
}

if($CurrentComplianceRecordingApplications.ComplianceRecordingPairedApplications.Count -gt 0){
Set-CsTeamsComplianceRecordingApplication `
-Identity "$Identity + '/' + $Instance" `
-ComplianceRecordingPairedApplications @(New-CsTeamsComplianceRecordingPairedApplication `
-Id $CurrentComplianceRecordingApplications.ComplianceRecordingPairedApplications)
}
}
$NewCsTeamsComplianceRecordingApplication = Get-CsTeamsComplianceRecordingApplication | Where-Object{$_.Identity -match $Identity}
Set-CsTeamsComplianceRecordingPolicy -Identity $Identity -ComplianceRecordingApplications $NewCsTeamsComplianceRecordingApplication
}

}
elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present')
{
Expand All @@ -217,6 +283,46 @@ function Set-TargetResource
}

Set-CsTeamsComplianceRecordingPolicy @UpdateParameters | Out-Null
if($ComplianceRecordingApplications.Count -gt 0){
foreach($CurrentComplianceRecordingApplications in $ComplianceRecordingApplications){
$Instance = $CurrentComplianceRecordingApplications.Id
$RequiredBeforeMeetingJoin = $CurrentComplianceRecordingApplications.RequiredBeforeMeetingJoin
$RequiredBeforeCallEstablishment = $CurrentComplianceRecordingApplications.RequiredBeforeCallEstablishment
$RequiredDuringMeeting = $CurrentComplianceRecordingApplications.RequiredDuringMeeting
$RequiredDuringCall = $CurrentComplianceRecordingApplications.RequiredDuringCall
$ConcurrentInvitationCount = $CurrentComplianceRecordingApplications.ConcurrentInvitationCount

$CsTeamsComplianceRecordingApplicationIdentity = $Identity + '/' + $Instance

$CsTeamsComplianceRecordingApplication = Get-CsTeamsComplianceRecordingApplication -Identity $CsTeamsComplianceRecordingApplicationIdentity -ErrorAction SilentlyContinue
if($null -eq $CsTeamsComplianceRecordingApplication){
New-CsTeamsComplianceRecordingApplication `
-RequiredBeforeMeetingJoin $RequiredBeforeMeetingJoin `
-RequiredBeforeCallEstablishment $RequiredBeforeCallEstablishment `
-RequiredDuringMeeting $RequiredDuringMeeting `
-RequiredDuringCall $RequiredDuringCall `
-ConcurrentInvitationCount $ConcurrentInvitationCount `
-Parent $Identity -Id $Instance
}
else{
Set-CsTeamsComplianceRecordingApplication `
-Identity $CsTeamsComplianceRecordingApplicationIdentity `
-RequiredBeforeMeetingJoin $RequiredBeforeMeetingJoin `
-RequiredBeforeCallEstablishment $RequiredBeforeCallEstablishment `
-RequiredDuringMeeting $RequiredDuringMeeting `
-RequiredDuringCall $RequiredDuringCall `
-ConcurrentInvitationCount $ConcurrentInvitationCount
}

if($CurrentComplianceRecordingApplications.ComplianceRecordingPairedApplications.Count -gt 0){
[string]$CsTeamsComplianceRecordingApplicationIdentity = $Identity + '/' + $Instance
[string]$ComplianceRecordingPairedApplications = $CurrentComplianceRecordingApplications.ComplianceRecordingPairedApplications
Set-CsTeamsComplianceRecordingApplication -Identity $CsTeamsComplianceRecordingApplicationIdentity -ComplianceRecordingPairedApplications @(New-CsTeamsComplianceRecordingPairedApplication -Id $ComplianceRecordingPairedApplications)
}
}
$NewCsTeamsComplianceRecordingApplication = Get-CsTeamsComplianceRecordingApplication | Where-Object{$_.Identity -match $Identity}
Set-CsTeamsComplianceRecordingPolicy -Identity $Identity -ComplianceRecordingApplications $NewCsTeamsComplianceRecordingApplication
}
}
elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present')
{
Expand All @@ -236,7 +342,7 @@ function Test-TargetResource
$Identity,

[Parameter()]
[System.String[]]
[Microsoft.Management.Infrastructure.CimInstance[]]
$ComplianceRecordingApplications,

[Parameter()]
Expand Down Expand Up @@ -300,6 +406,30 @@ function Test-TargetResource
Write-Verbose -Message "Test-TargetResource returned $false"
return $false
}
$testResult = $true

#Compare Cim instances
foreach ($key in $PSBoundParameters.Keys)
{
$source = $PSBoundParameters.$key
$target = $CurrentValues.$key
if ($source.getType().Name -like '*CimInstance*')
{
$source = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $source

$testResult = Compare-M365DSCComplexObject `
-Source ($source) `
-Target ($target)

if (-Not $testResult)
{
$testResult = $false
break
}

$ValuesToCheck.Remove($key) | Out-Null
}
}

Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)"
Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)"
Expand All @@ -314,10 +444,13 @@ function Test-TargetResource
}
}

$testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues `
-Source $($MyInvocation.MyCommand.Source) `
-DesiredValues $PSBoundParameters `
-ValuesToCheck $ValuesToCheck.Keys
if ($testResult)
{
$testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues `
-Source $($MyInvocation.MyCommand.Source) `
-DesiredValues $PSBoundParameters `
-ValuesToCheck $ValuesToCheck.Keys
}

Write-Verbose -Message "Test-TargetResource returned $testResult"

Expand Down Expand Up @@ -406,11 +539,42 @@ function Export-TargetResource
$Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode `
-Results $Results

if ($null -ne $Results.ComplianceRecordingApplications)
{
$complexMapping = @(
@{
Name = 'ComplianceRecordingApplications'
CimInstanceName = 'TeamsComplianceRecordingApplication'
IsRequired = $False
}
)
$complexTypeStringResult = Get-M365DSCDRGComplexTypeToString `
-ComplexObject $Results.ComplianceRecordingApplications `
-CIMInstanceName 'TeamsComplianceRecordingApplication' `
-ComplexTypeMapping $complexMapping

if (-Not [String]::IsNullOrWhiteSpace($complexTypeStringResult))
{
$Results.ComplianceRecordingApplications = $complexTypeStringResult
}
else
{
$Results.Remove('ComplianceRecordingApplications') | Out-Null
}
}

$currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName `
-ConnectionMode $ConnectionMode `
-ModulePath $PSScriptRoot `
-Results $Results `
-Credential $Credential
if ($Results.ComplianceRecordingApplications)
{
$currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ComplianceRecordingApplications' -IsCIMArray:$True
$currentDSCBlock = $currentDSCBlock.Replace('ComplianceRecordingApplications = @("', 'ComplianceRecordingApplications = @(')
$currentDSCBlock = $currentDSCBlock.Replace(" `",`"`r`n", '')

}
$dscContent += $currentDSCBlock
Save-M365DSCPartialExport -Content $currentDSCBlock `
-FileName $Global:PartialExportFileName
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
[ClassVersion("1.0.0")]
class MSFT_TeamsComplianceRecordingApplication
{
[Write, Description("A name that uniquely identifies the application instance of the policy-based recording application.")] String Id;
[Write, Description("Determines the other policy-based recording applications to pair with this application to achieve application resiliency. Can only have one paired application.")] String ComplianceRecordingPairedApplications[];
[Write, Description("Indicates whether the policy-based recording application must be in the meeting before the user is allowed to join the meeting.")] Boolean RequiredBeforeMeetingJoin;
[Write, Description("Indicates whether the policy-based recording application must be in the call before the call is allowed to establish.")] Boolean RequiredBeforeCallEstablishment;
[Write, Description("Indicates whether the policy-based recording application must be in the meeting while the user is in the meeting.")] Boolean RequiredDuringMeeting;
[Write, Description("Indicates whether the policy-based recording application must be in the call while the call is active.")] Boolean RequiredDuringCall;
[Write, Description("Determines the number of invites to send out to the application instance of the policy-based recording application. Can be set to 1 or 2 only.")] String ConcurrentInvitationCount;
};

[ClassVersion("1.0.0.0"), FriendlyName("TeamsComplianceRecordingPolicy")]
class MSFT_TeamsComplianceRecordingPolicy : OMI_BaseResource
{
[Key, Description("Unique identifier of the application instance of a policy-based recording application to be retrieved.")] String Identity;
[Write, Description("A list of application instances of policy-based recording applications to assign to this policy. The Id of each of these application instances must be the ObjectId of the application instance as obtained by the Get-CsOnlineApplicationInstance cmdlet.")] String ComplianceRecordingApplications[];
[Write, Description("A list of application instances of policy-based recording applications to assign to this policy. The Id of each of these application instances must be the ObjectId of the application instance as obtained by the Get-CsOnlineApplicationInstance cmdlet."), EmbeddedInstance("MSFT_TeamsComplianceRecordingApplication")] String ComplianceRecordingApplications[];
NikCharlebois marked this conversation as resolved.
Show resolved Hide resolved
[Write, Description("Enables administrators to provide explanatory text to accompany a Teams recording policy. For example, the Description might include information about the users the policy should be assigned to.")] String Description;
[Write, Description("Setting this attribute to true disables recording audio notifications for 1:1 calls that are under compliance recording.")] Boolean DisableComplianceRecordingAudioNotificationForCalls;
[Write, Description("Controls whether this Teams recording policy is active or not.")] Boolean Enabled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,34 @@ Configuration Example

node localhost
{
TeamsComplianceRecordingPolicy 'Example'
TeamsComplianceRecordingPolicy "TeamsComplianceRecordingPolicy-Tag:MyTeamsComplianceRecordingPolicy"
{
ComplianceRecordingApplications = @();
Credential = $Credscredential;
Credential = $credsCredential;
ComplianceRecordingApplications = @(
MSFT_TeamsComplianceRecordingApplication{
Id = '00000000-0000-0000-0000-000000000000'
ComplianceRecordingPairedApplications = @('00000000-0000-0000-0000-000000000000')
ConcurrentInvitationCount = 1
RequiredDuringCall = $True
RequiredBeforeMeetingJoin = $True
RequiredBeforeCallEstablishment = $True
RequiredDuringMeeting = $True
}
MSFT_TeamsComplianceRecordingApplication{
Id = '12345678-0000-0000-0000-000000000000'
ComplianceRecordingPairedApplications = @('87654321-0000-0000-0000-000000000000')
ConcurrentInvitationCount = 1
RequiredDuringCall = $True
RequiredBeforeMeetingJoin = $True
RequiredBeforeCallEstablishment = $True
RequiredDuringMeeting = $True
}
);
Description = "MyTeamsComplianceRecordingPolicy";
DisableComplianceRecordingAudioNotificationForCalls = $False;
Enabled = $False;
Enabled = $True;
Ensure = "Present";
Identity = "Global";
Identity = "Tag:MyTeamsComplianceRecordingPolicy";
WarnUserOnRemoval = $True;
}
}
}
Loading
Loading