Skip to content

Commit

Permalink
Merge pull request #447 from NikCharlebois/AADMSGroupLifecyclePolicy
Browse files Browse the repository at this point in the history
AADMSGroupLifecyclePolicy
  • Loading branch information
NikCharlebois authored Apr 8, 2020
2 parents aa3d247 + 59bb047 commit 6fa01a8
Show file tree
Hide file tree
Showing 10 changed files with 5,036 additions and 840 deletions.
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

* AADMSGroupLifecyclePolicy
* Initial Release;
* AADGroupsNamingPolicy
* Initial Release;
* SPOPropertyBag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ function Get-TargetResource

if ($null -eq $Policy)
{
New-Office365DSCLogEntry -Error $_ -Message "Couldn't get AzureAD Group Naming Policy" -Source $MyInvocation.MyCommand.ModuleName
$currentValues = $PSBoundParameters
$currentValues.Ensure = "Absent"
return $currentValues
Expand Down Expand Up @@ -91,7 +90,7 @@ function Set-TargetResource
$GlobalAdminAccount
)

Write-Verbose -Message "Setting configuration of Device Conditional Access Policy for $Name"
Write-Verbose -Message "Setting configuration of Azure AD Groups Naming Policy"
#region Telemetry
$data = [System.Collections.Generic.Dictionary[[String], [String]]]::new()
$data.Add("Resource", $MyInvocation.MyCommand.ModuleName)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
function Get-TargetResource
{
[CmdletBinding()]
[OutputType([System.Collections.Hashtable])]
param
(
[Parameter(Mandatory = $true)]
[System.String]
[ValidateSet('Yes')]
$IsSingleInstance,

[Parameter(Mandatory = $true)]
[System.UInt32]
$GroupLifetimeInDays,

[Parameter(Mandatory = $true)]
[System.String]
[ValidateSet('All', 'Selected', 'None')]
$ManagedGroupTypes,

[Parameter(Mandatory = $true)]
[System.String[]]
$AlternateNotificationEmails,

[Parameter()]
[ValidateSet('Present', 'Absent')]
[System.String]
$Ensure = 'Present',

[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$GlobalAdminAccount
)

Write-Verbose -Message "Getting configuration of AzureAD Groups Lifecycle Policy"
#region Telemetry
$data = [System.Collections.Generic.Dictionary[[String], [String]]]::new()
$data.Add("Resource", $MyInvocation.MyCommand.ModuleName)
$data.Add("Method", $MyInvocation.MyCommand)
Add-O365DSCTelemetryEvent -Data $data
#endregion

Test-MSCloudLogin -CloudCredential $GlobalAdminAccount `
-Platform AzureAD

try
{
$Policy = Get-AzureADMSGroupLifecyclePolicy -ErrorAction SilentlyContinue
}
catch
{
Write-Verbose -Message $_
}

if ($null -eq $Policy)
{
$currentValues = $PSBoundParameters
$currentValues.Ensure = "Absent"
return $currentValues
}
else
{
Write-Verbose "Found existing AzureAD Groups Lifecycle Policy"
$result = @{
IsSingleInstance = 'Yes'
GroupLifetimeInDays = $Policy.GroupLifetimeInDays
ManagedGroupTypes = $Policy.ManagedGroupTypes
AlternateNotificationEmails = $Policy.AlternateNotificationEmails.Split(';')
Ensure = "Present"
GlobalAdminAccount = $GlobalAdminAccount
}

Write-Verbose -Message "Get-TargetResource Result: `n $(Convert-O365DscHashtableToString -Hashtable $result)"
return $result
}
}

function Set-TargetResource
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
[ValidateSet('Yes')]
$IsSingleInstance,

[Parameter(Mandatory = $true)]
[System.UInt32]
$GroupLifetimeInDays,

[Parameter(Mandatory = $true)]
[System.String]
[ValidateSet('All', 'Selected', 'None')]
$ManagedGroupTypes,

[Parameter(Mandatory = $true)]
[System.String[]]
$AlternateNotificationEmails,

[Parameter()]
[ValidateSet('Present', 'Absent')]
[System.String]
$Ensure = 'Present',

[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$GlobalAdminAccount
)

Write-Verbose -Message "Setting configuration of Azure AD Groups Lifecycle Policy"
#region Telemetry
$data = [System.Collections.Generic.Dictionary[[String], [String]]]::new()
$data.Add("Resource", $MyInvocation.MyCommand.ModuleName)
$data.Add("Method", $MyInvocation.MyCommand)
Add-O365DSCTelemetryEvent -Data $data
#endregion

Test-MSCloudLogin -CloudCredential $GlobalAdminAccount `
-Platform AzureAD

try
{
$policy = Get-AzureADMSGroupLifecyclePolicy -ErrorAction SilentlyContinue
}
catch
{
Write-Verbose $_
return
}

$currentPolicy = Get-TargetResource @PSBoundParameters

if ($Ensure -eq "Present" -and $currentPolicy.Ensure -eq "Absent")
{
Write-Verbose -Message "The Group Lifecycle Policy should exist but it doesn't. Creating it."
$creationParams = $PSBoundParameters
$creationParams.Remove("IsSingleInstance")
$creationParams.Remove("GlobalAdminAccount")
$creationParams.Remove("Ensure")

$emails = ""
foreach ($email in $creationParams.AlternateNotificationEmails)
{
$emails += $email + ";"
}
$emails = $emails.TrimEnd(';')
$creationParams.AlternateNotificationEmails = $emails
New-AzureADMSGroupLifecyclePolicy @creationParams
}
elseif ($Ensure -eq 'Present' -and $currentPolicy.Ensure -eq 'Present')
{
$updateParams = $PSBoundParameters
$updateParams.Remove("IsSingleInstance")
$updateParams.Remove("GlobalAdminAccount")
$updateParams.Remove("Ensure")

$emails = ""
foreach ($email in $updateParams.AlternateNotificationEmails)
{
$emails += $email + ";"
}
$emails = $emails.TrimEnd(';')
$updateParams.AlternateNotificationEmails = $emails
$updateParams.Add("Id", (Get-AzureADMSGroupLifecyclePolicy).Id)

Write-Verbose -Message "The Group Lifecycle Policy exists but it's not in the Desired State. Updating it."
Set-AzureADMSGroupLifecyclePolicy @updateParams
}
elseif ($Ensure -eq 'Absent' -and $currentPolicy.Ensure -eq 'Present')
{
Write-Verbose -Message "The Group Lifecycle Policy should NOT exist but it DOES. Removing it."
Remove-AzureADMSGroupLifecyclePolicy -Id (Get-AzureADMSGroupLifecyclePolicy).Id
}
}

function Test-TargetResource
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[Parameter(Mandatory = $true)]
[System.String]
[ValidateSet('Yes')]
$IsSingleInstance,

[Parameter(Mandatory = $true)]
[System.UInt32]
$GroupLifetimeInDays,

[Parameter(Mandatory = $true)]
[System.String]
[ValidateSet('All', 'Selected', 'None')]
$ManagedGroupTypes,

[Parameter(Mandatory = $true)]
[System.String[]]
$AlternateNotificationEmails,

[Parameter()]
[ValidateSet('Present', 'Absent')]
[System.String]
$Ensure = 'Present',

[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$GlobalAdminAccount
)

Write-Verbose -Message "Testing configuration of AzureAD Groups Lifecycle Policy"

$CurrentValues = Get-TargetResource @PSBoundParameters
Write-Verbose -Message "Target Values: $(Convert-O365DscHashtableToString -Hashtable $PSBoundParameters)"

$ValuesToCheck = $PSBoundParameters
$ValuesToCheck.Remove('GlobalAdminAccount') | Out-Null

$TestResult = Test-Office365DSCParameterState -CurrentValues $CurrentValues `
-Source $($MyInvocation.MyCommand.Source) `
-DesiredValues $PSBoundParameters `
-ValuesToCheck $ValuesToCheck.Keys

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

return $TestResult
}

function Export-TargetResource
{
[CmdletBinding()]
[OutputType([System.String])]
param
(
[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$GlobalAdminAccount
)
$InformationPreference = 'Continue'
#region Telemetry
$data = [System.Collections.Generic.Dictionary[[String], [String]]]::new()
$data.Add("Resource", $MyInvocation.MyCommand.ModuleName)
$data.Add("Method", $MyInvocation.MyCommand)
Add-O365DSCTelemetryEvent -Data $data
#endregion

try
{
$Policy = Get-AzureADMSGroupLifecyclePolicy -ErrorAction SilentlyContinue
}
catch
{
return ""
}
$content = ''
$organization = ""
$principal = "" # Principal represents the "NetBios" name of the tenant (e.g. the O365DSC part of O365DSC.onmicrosoft.com)
if ($GlobalAdminAccount.UserName.Contains("@"))
{
$organization = $GlobalAdminAccount.UserName.Split("@")[1]

if ($organization.IndexOf(".") -gt 0)
{
$principal = $organization.Split(".")[0]
}
}
$params = @{
GlobalAdminAccount = $GlobalAdminAccount
IsSingleInstance = 'Yes'
GroupLifetimeInDays = 1
ManagedGroupTypes = 'All'
AlternateNotificationEmails = '[email protected]'
}
$result = Get-TargetResource @params
$result.GlobalAdminAccount = Resolve-Credentials -UserName "globaladmin"
$content += " AADMSGroupLifecyclePolicy " + (New-GUID).ToString() + "`r`n"
$content += " {`r`n"
$partialContent = Get-DSCBlock -Params $result -ModulePath $PSScriptRoot
$partialContent = Convert-DSCStringParamToVariable -DSCBlock $partialContent -ParameterName "GlobalAdminAccount"

if ($partialContent.ToLower().Contains("@" + $principal.ToLower()))
{
$partialContent = $partialContent -ireplace [regex]::Escape("@" + $principal), "@`$OrganizationName.Split('.')[0])"
}
$content += $partialContent
$content += " }`r`n"

return $content
}

Export-ModuleMember -Function *-TargetResource
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[ClassVersion("1.0.0.0"), FriendlyName("AADMSGroupLifecyclePolicy")]
class MSFT_AADMSGroupLifecyclePolicy : OMI_BaseResource
{
[Key, Description("Only valid value is 'Yes'."), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance;
[Required, Description("The number of days a group can exist before it needs to be renewed.")] UInt32 GroupLifetimeInDays;
[Required, Description("This parameter allows the admin to select which office 365 groups the policy will apply to. 'None' will create the policy in a disabled state. 'All' will apply the policy to every Office 365 group in the tenant. 'Selected' will allow the admin to choose specific Office 365 groups that the policy will apply to."), ValueMap{"All","None", "Selected"}, Values{"All","None", "Selected"}] String ManagedGroupTypes;
[Required, Description("Notification emails for groups that have no owners will be sent to these email addresses.")] String AlternateNotificationEmails[];
[Write, Description("Specify if the Azure AD Groups Lifecycle Policy should exist or not."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;
[Required, Description("Credentials of the Azure Active Directory Admin"), EmbeddedInstance("MSFT_Credential")] String GlobalAdminAccount;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# AADMSGroupLifecyclePolicy

## Description

This resource configures an Azure Active Directory Group Lifecycle Policy (e.g. Expiration).
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<#
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]
$credsGlobalAdmin
)
Import-DscResource -ModuleName Office365DSC

node localhost
{
AADMSGroupLifecyclePolicy GroupLifecyclePolicy
{
AlternateNotificationEmails = @("[email protected]");
Ensure = "Present";
GlobalAdminAccount = $credsGlobalAdmin;
GroupLifetimeInDays = 99;
IsSingleInstance = "Yes";
ManagedGroupTypes = "Selected";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture {
Assert-MockCalled -CommandName "Get-AzureADDirectorySetting" -Exactly 1
}
$Script:calledOnceAlready = $false
It 'Should return true from the Test method' {
It 'Should return false from the Test method' {
Test-TargetResource @testParams | Should Be $false
}
$Script:calledOnceAlready = $false
Expand Down
Loading

0 comments on commit 6fa01a8

Please sign in to comment.