Skip to content

Commit

Permalink
Merge pull request #5029 from PetRich-MSFT/AuditRetentionPolicy
Browse files Browse the repository at this point in the history
Implement SCUnifiedAuditLogRetentionPolicy Resource
  • Loading branch information
NikCharlebois committed Sep 11, 2024
2 parents e347956 + f7071b2 commit daa93c5
Show file tree
Hide file tree
Showing 8 changed files with 889 additions and 1 deletion.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[ClassVersion("1.0.0.0"), FriendlyName("SCUnifiedAuditLogRetentionPolicy")]
class MSFT_SCUnifiedAuditLogRetentionPolicy : OMI_BaseResource
{
[Write, Description("The description for the audit log retention policy")] String Description;
[Key, Description("Unique name for the audit log retention policy")] String Name;
[Write, Description("Specifies the audit log operations that are retained by the policy")] String Operations[];
[Write, Description("Priority value for the policy that determines the order of policy processing.")] UInt32 Priority;
[Write, Description("Specifies the audit logs of a specific record type that are retained by the policy.")] String RecordTypes[];
[Write, Description("How long audit log records are kept"), ValueMap{"SevenDays", "OneMonth", "ThreeMonths", "SixMonths", "NineMonths", "TwelveMonths", "ThreeYears", "FiveYears", "SevenYears", "TenYears"}, Values{"SevenDays", "OneMonth", "ThreeMonths", "SixMonths", "NineMonths", "TwelveMonths", "ThreeYears", "FiveYears", "SevenYears", "TenYears"}] String RetentionDuration;
[Write, Description("Specifies the audit logs that are retained by the policy based on the ID of the user who performed the action")] String UserIds[];
[Write, Description("Present ensures the instance exists, absent ensures it is removed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure;
[Write, Description("Credentials of the workload's Admin"), EmbeddedInstance("MSFT_Credential")] string Credential;
[Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId;
[Write, Description("Id of the Azure Active Directory tenant used for authentication.")] String TenantId;
[Write, Description("Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication.")] String CertificateThumbprint;
[Write, Description("Secret of the Azure Active Directory tenant used for authentication."), EmbeddedInstance("MSFT_Credential")] String ApplicationSecret;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

# SCUnifiedAuditLogRetentionPolicy

## Description

The resource configured the Unified Audit Log Retention Policy in the Security and Compliance.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"resourceName": "SCUnifiedAuditLogRetentionPolicy",
"description": "The resource configured the Unified Audit Log Retention Policy in the Security and Compliance.",
"permissions":[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<#
This example is used to test new resources and showcase the usage of new resources being worked on.
It is not meant to use as a production baseline.
#>

Configuration Example
{
param(
[Parameter(Mandatory = $true)]
[PSCredential]
$Credentials
)
Import-DscResource -ModuleName Microsoft365DSC

node localhost
{
SCUnifiedAuditLogRetentionPolicy 'Example'
{
Credential = $Credentials;
Ensure = "Present";
Name = "Test Policy";
Priority = 1;
RetentionDuration = "SevenDays";
}
}
}
22 changes: 21 additions & 1 deletion ResourceGenerator/M365DSCResourceGenerator.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -911,10 +911,24 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments
}
else
{
$ParametersToFilterOut = @('Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable', 'WhatIf', 'Confirm')
$ParametersToFilterOut = @('Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable', 'WhatIf', 'Confirm', 'ProgressAction')
$cmdlet = Get-Command ($cmdletVerb + "-" + $cmdletNoun)

$defaultParameterSetProperties = $cmdlet.ParameterSets | Where-Object -FilterScript {$_.IsDefault}

if ($null -eq $defaultParameterSetProperties)
{
# No default parameter set, if there is only a single parameter set then use that
if ($cmdlet.ParameterSets.Count -eq 1)
{
$defaultParameterSetProperties = $cmdlet.ParameterSets[0]
}
else
{
throw "CmdLet '$($cmdletVerb + "-" + $cmdletNoun)' does not have a default parameter set"
}
}

$properties = $defaultParameterSetProperties.Parameters | Where-Object -FilterScript {-not $ParametersToFilterOut.Contains($_.Name) -and -not $_.Name.StartsWith('MsftInternal')}

#region Get longest parametername
Expand Down Expand Up @@ -1128,6 +1142,12 @@ class MSFT_DeviceManagementConfigurationPolicyAssignments

$propertyValue = $null
$propertyDriftValue = $null

if ($null -eq $fakeValues.$key)
{
continue
}

switch ($fakeValues.$key.GetType().Name)
{
"String"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
[CmdletBinding()]
param(
)
$M365DSCTestFolder = Join-Path -Path $PSScriptRoot `
-ChildPath '..\..\Unit' `
-Resolve
$CmdletModule = (Join-Path -Path $M365DSCTestFolder `
-ChildPath '\Stubs\Microsoft365.psm1' `
-Resolve)
$GenericStubPath = (Join-Path -Path $M365DSCTestFolder `
-ChildPath '\Stubs\Generic.psm1' `
-Resolve)
Import-Module -Name (Join-Path -Path $M365DSCTestFolder `
-ChildPath '\UnitTestHelper.psm1' `
-Resolve)

$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule `
-DscResource "SCUnifiedAuditLogRetentionPolicy" -GenericStubModule $GenericStubPath
Describe -Name $Global:DscHelper.DescribeHeader -Fixture {
InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock {
Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope
BeforeAll {

$secpasswd = ConvertTo-SecureString (New-Guid | Out-String) -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ('tenantadmin@mydomain.com', $secpasswd)

Mock -CommandName Confirm-M365DSCDependencies -MockWith {
}

Mock -CommandName Get-PSSession -MockWith {
}

Mock -CommandName Remove-PSSession -MockWith {
}

Mock -CommandName Set-UnifiedAuditLogRetentionPolicy -MockWith {
}

Mock -CommandName New-UnifiedAuditLogRetentionPolicy -MockWith {
}

Mock -CommandName Remove-UnifiedAuditLogRetentionPolicy -MockWith {
}

Mock -CommandName New-M365DSCConnection -MockWith {
return "Credentials"
}

# Mock Write-Host to hide output during the tests
Mock -CommandName Write-Host -MockWith {
}
$Script:exportedInstances =$null
$Script:ExportMode = $false
}
# Test contexts
Context -Name "The SCUnifiedAuditLogRetentionPolicy should exist but it DOES NOT" -Fixture {
BeforeAll {
$testParams = @{
Name = "Test Policy"
Priority = 42
RetentionDuration = "SevenDays"
Ensure = "Present"
Credential = $Credential;
}

Mock -CommandName Get-UnifiedAuditLogRetentionPolicy -MockWith {
return $null
}
}
It 'Should return Values from the Get method' {
(Get-TargetResource @testParams).Ensure | Should -Be 'Absent'
}
It 'Should return false from the Test method' {
Test-TargetResource @testParams | Should -Be $false
}
It 'Should Create the Unified Audit Log Retention Policy from the Set method' {
Set-TargetResource @testParams
Should -Invoke -CommandName New-UnifiedAuditLogRetentionPolicy -Exactly 1
}
}

Context -Name "The SCUnifiedAuditLogRetentionPolicy exists but it SHOULD NOT" -Fixture {
BeforeAll {
$testParams = @{
Name = "Test Policy"
Priority = 42
RetentionDuration = "SevenDays"
Ensure = "Absent"
Credential = $Credential;
}

Mock -CommandName Get-UnifiedAuditLogRetentionPolicy -MockWith {
return @{
Identity = "TestIdentity"
Priority = $testParams.Priority
Name = $testParams.Name
RetentionDuration = $testParams.RetentionDuration
}
}
}

It 'Should return Values from the Get method' {
(Get-TargetResource @testParams).Ensure | Should -Be 'Present'
}

It 'Should return false from the Test method' {
Test-TargetResource @testParams | Should -Be $false
}

It 'Should Remove the group from the Set method' {
Set-TargetResource @testParams
Should -Invoke -CommandName Remove-UnifiedAuditLogRetentionPolicy -Exactly 1
}
}
Context -Name "The SCUnifiedAuditLogRetentionPolicy Exists and Values are already in the desired state" -Fixture {
BeforeAll {
$testParams = @{
Name = "Test Policy"
Priority = 42
RetentionDuration = "SevenDays"
Ensure = 'Present'
Credential = $Credential;
}

Mock -CommandName Get-UnifiedAuditLogRetentionPolicy -MockWith {
return @{
Name = "Test Policy"
Priority = 42
RetentionDuration = "SevenDays"
}
}
}


It 'Should return true from the Test method' {
Test-TargetResource @testParams | Should -Be $true
}
}

Context -Name "The SCUnifiedAuditLogRetentionPolicy exists and values are NOT in the desired state" -Fixture {
BeforeAll {
$testParams = @{
Name = "Test Policy"
Priority = 42
RetentionDuration = "SevenDays"
Description = "FakeStringValueDrift"
Ensure = 'Present'
Credential = $Credential;
}

Mock -CommandName Get-UnifiedAuditLogRetentionPolicy -MockWith {
return @{
Identity = "TestIdentity"
Name = $testParams.Name
Priority = $testParams.Priority
RetentionDuration = $testParams.RetentionDuration
Description = $testParams.RetentionDescription + "#Drift"
}
}
}

It 'Should return Values from the Get method' {
(Get-TargetResource @testParams).Ensure | Should -Be 'Present'
}

It 'Should return false from the Test method' {
Test-TargetResource @testParams | Should -Be $false
}

It 'Should call the Set method' {
Set-TargetResource @testParams
Should -Invoke -CommandName Set-UnifiedAuditLogRetentionPolicy -Exactly 1
}
}

Context -Name 'ReverseDSC Tests' -Fixture {
BeforeAll {
$Global:CurrentModeIsExport = $true
$Global:PartialExportFileName = "$(New-Guid).partial.ps1"
$testParams = @{
Credential = $Credential
}

Mock -CommandName Get-UnifiedAuditLogRetentionPolicy -MockWith {
return @{
Priority = 3
Name = "FakeStringValue"
Description = "FakeStringValue"
RetentionDuration = "SevenDays"
Identity = "FakeIdentity"
}
}
}
It 'Should Reverse Engineer resource from the Export method' {
$result = Export-TargetResource @testParams
$result | Should -Not -BeNullOrEmpty
}
}

Context -Name 'Does not return resources that are pending deletion' -Fixture {
BeforeAll {
$testParams = @{
Name = "Test Policy"
Priority = 42
RetentionDuration = "SevenDays"
Ensure = 'Present'
Credential = $Credential;
}

Mock -CommandName Get-UnifiedAuditLogRetentionPolicy -MockWith {
return @{
Name = "Test Policy"
Priority = 42
RetentionDuration = "SevenDays"
Mode = "PendingDeletion"
}
}
}

It 'Should return false from the Test method' {
Test-TargetResource @testParams | Should -Be $false
}
}
}
}

Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope
Loading

0 comments on commit daa93c5

Please sign in to comment.