Skip to content

Commit

Permalink
Merge pull request #3909 from microsoft/Dev
Browse files Browse the repository at this point in the history
Release 1.23.1115.1
  • Loading branch information
NikCharlebois authored Nov 16, 2023
2 parents c4e8923 + 433af4d commit b2ccc65
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 64 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Change log for Microsoft365DSC

# 1.23.1115.1

* AADApplication
* Added support for the IsFallbackPublicClient property.
FIXES [#3906](https://github.com/microsoft/Microsoft365DSC/issues/3906)
* AADServicePrincipal
* Added support to define members.
FIXES [#3902](https://github.com/microsoft/Microsoft365DSC/issues/3902)
* EXOCASMailboxPlan
* Fixes an issue where we are not able to set the settings of a CAS
Mailbox Plan by specifying the Identity without the GUID in the name.
FIXES [#3900](https://github.com/microsoft/Microsoft365DSC/issues/3900)

# 1.23.1108.3

* AADRoleEligibilityScheduleRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ function Get-TargetResource
[System.String[]]
$IdentifierUris,

[Parameter()]
[System.Boolean]
$IsFallbackPublicClient,

[Parameter()]
[System.String]
$LogoutURL,
Expand Down Expand Up @@ -177,12 +181,18 @@ function Get-TargetResource
}
}

$IsFallbackPublicClientValue = $false
if ($AADApp.IsFallbackPublicClient)
{
$IsFallbackPublicClientValue = $AADApp.IsFallbackPublicClient
}
$result = @{
DisplayName = $AADApp.DisplayName
AvailableToOtherTenants = $AvailableToOtherTenantsValue
GroupMembershipClaims = $AADApp.GroupMembershipClaims
Homepage = $AADApp.web.HomepageUrl
IdentifierUris = $AADApp.IdentifierUris
IsFallbackPublicClient = $IsFallbackPublicClientValue
KnownClientApplications = $AADApp.Api.KnownClientApplications
LogoutURL = $AADApp.web.LogoutURL
PublicClient = $isPublicClient
Expand Down Expand Up @@ -259,6 +269,10 @@ function Set-TargetResource
[System.String[]]
$KnownClientApplications,

[Parameter()]
[System.Boolean]
$IsFallbackPublicClient,

[Parameter()]
[System.String]
$LogoutURL,
Expand Down Expand Up @@ -680,6 +694,10 @@ function Test-TargetResource
[System.String[]]
$IdentifierUris,

[Parameter()]
[System.Boolean]
$IsFallbackPublicClient,

[Parameter()]
[System.String[]]
$KnownClientApplications,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class MSFT_AADApplication : OMI_BaseResource
[Write, Description("A bitmask that configures the groups claim issued in a user or OAuth 2.0 access token that the application expects. The bitmask values are: 0: None, 1: Security groups and Azure AD roles, 2: Reserved, and 4: Reserved. Setting the bitmask to 7 will get all of the security groups, distribution groups, and Azure AD directory roles that the signed-in user is a member of.")] String GroupMembershipClaims;
[Write, Description("The URL to the application's homepage.")] String Homepage;
[Write, Description("User-defined URI(s) that uniquely identify a Web application within its Azure AD tenant, or within a verified custom domain.")] string IdentifierUris[];
[Write, Description("Specifies the fallback application type as public client, such as an installed application running on a mobile device. The default value is false, which means the fallback application type is confidential client such as web app. There are certain scenarios where Microsoft Entra ID cannot determine the client application type (for example, ROPC flow where it is configured without specifying a redirect URI). In those cases, Microsoft Entra ID will interpret the application type based on the value of this property.")] Boolean IsFallbackPublicClient;
[Write, Description("Client applications that are tied to this resource application.")] string KnownClientApplications[];
[Write, Description("The logout url for this application.")] string LogoutURL;
[Write, Description("Specifies whether this application is a public client (such as an installed application running on a mobile device). Default is false.")] Boolean PublicClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ function Get-TargetResource
[System.String]
$AppId,

[Parameter()]
[Microsoft.Management.Infrastructure.CimInstance[]]
$AppRoleAssignedTo,

[Parameter()]
[System.String]
$ObjectId,
Expand Down Expand Up @@ -125,6 +129,7 @@ function Get-TargetResource
else
{
$AADServicePrincipal = Get-MgServicePrincipal -ServicePrincipalId $ObjectId `
-Expand 'AppRoleAssignedTo' `
-ErrorAction Stop
}
}
Expand All @@ -142,7 +147,8 @@ function Get-TargetResource
}
else
{
$AADServicePrincipal = Get-MgServicePrincipal -Filter "AppID eq '$($AppId)'"
$AADServicePrincipal = Get-MgServicePrincipal -Filter "AppID eq '$($AppId)'" `
-Expand 'AppRoleAssignedTo'
}
}
if ($null -eq $AADServicePrincipal)
Expand All @@ -151,8 +157,32 @@ function Get-TargetResource
}
else
{
$AppRoleAssignedToValues = @()
foreach ($principal in $AADServicePrincipal.AppRoleAssignedTo)
{
$currentAssignment = @{
PrincipalType = $null
Identity = $null
}
if ($principal.PrincipalType -eq 'User')
{
$user = Get-MgUser -UserId $principal.PrincipalId
$currentAssignment.PrincipalType = 'User'
$currentAssignment.Identity = $user.UserPrincipalName.Split('@')[0]
$AppRoleAssignedToValues += $currentAssignment
}
elseif ($principal.PrincipalType -eq 'Group')
{
$group = Get-MgGroup -GroupId $principal.PrincipalId
$currentAssignment.PrincipalType = 'Group'
$currentAssignment.Identity = $group.DisplayName
$AppRoleAssignedToValues += $currentAssignment
}
}

$result = @{
AppId = $AADServicePrincipal.AppId
AppRoleAssignedTo = $AppRoleAssignedToValues
ObjectID = $AADServicePrincipal.Id
DisplayName = $AADServicePrincipal.DisplayName
AlternativeNames = $AADServicePrincipal.AlternativeNames
Expand Down Expand Up @@ -181,6 +211,7 @@ function Get-TargetResource
}
catch
{
Write-Verbose -Message $_
New-M365DSCLogEntry -Message 'Error retrieving data:' `
-Exception $_ `
-Source $($MyInvocation.MyCommand.Source) `
Expand All @@ -200,6 +231,10 @@ function Set-TargetResource
[System.String]
$AppId,

[Parameter()]
[Microsoft.Management.Infrastructure.CimInstance[]]
$AppRoleAssignedTo,

[Parameter()]
[System.String]
$ObjectId,
Expand Down Expand Up @@ -286,11 +321,9 @@ function Set-TargetResource
$ManagedIdentity
)

Write-Verbose -Message "1 - There are now {$((Get-ChildItem function: | Measure-Object).Count) functions}"
$ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' `
-InboundParameters $PSBoundParameters

Write-Verbose -Message "2 - There are now {$((Get-ChildItem function: | Measure-Object).Count) functions}"
Write-Verbose -Message 'Setting configuration of Azure AD ServicePrincipal'
#Ensure the proper dependencies are installed in the current environment.
Confirm-M365DSCDependencies
Expand Down Expand Up @@ -319,6 +352,10 @@ function Set-TargetResource
# ServicePrincipal should exist but it doesn't
if ($Ensure -eq 'Present' -and $currentAADServicePrincipal.Ensure -eq 'Absent')
{
if ($null -ne $AppRoleAssignedTo)
{
$currentParameters.AppRoleAssignedTo = $AppRoleAssignedToValue
}
Write-Verbose -Message 'Creating new Service Principal'
New-MgServicePrincipal @currentParameters
}
Expand All @@ -328,7 +365,93 @@ function Set-TargetResource
Write-Verbose -Message 'Updating existing Service Principal'
Write-Verbose -Message "CurrentParameters: $($currentParameters | Out-String)"
Write-Verbose -Message "ServicePrincipalID: $($currentAADServicePrincipal.ObjectID)"
$currentParameters.Remove('AppRoleAssignedTo') | Out-Null
Update-MgServicePrincipal -ServicePrincipalId $currentAADServicePrincipal.ObjectID @currentParameters

if ($AppRoleAssignedTo)
{
[Array]$currentPrincipals = $currentAADServicePrincipal.AppRoleAssignedTo.Identity
[Array]$desiredPrincipals = $AppRoleAssignedTo.Identity

[Array]$differences = Compare-Object -ReferenceObject $currentPrincipals -DifferenceObject $desiredPrincipals
[Array]$membersToAdd = $differences | Where-Object -FilterScript {$_.SideIndicator -eq '=>'}
[Array]$membersToRemove = $differences | Where-Object -FilterScript {$_.SideIndicator -eq '<='}

if ($differences.Count -gt 0)
{
if ($membersToAdd.Count -gt 0)
{
$AppRoleAssignedToValues = @()
foreach ($assignment in $AppRoleAssignedTo)
{
$AppRoleAssignedToValues += @{
PrincipalType = $assignment.PrincipalType
Identity = $assignment.Identity
}
}
foreach ($member in $membersToAdd)
{
$assignment = $AppRoleAssignedToValues | Where-Object -FilterScript {$_.Identity -eq $member.InputObject}
if ($assignment.PrincipalType -eq 'User')
{
Write-Verbose -Message "Retrieving user {$($assignment.Identity)}"
$user = Get-MgUser -Filter "startswith(UserPrincipalName, '$($assignment.Identity)')"
$PrincipalIdValue = $user.Id
}
else
{
Write-Verbose -Message "Retrieving group {$($assignment.Identity)}"
$group = Get-MgGroup -Filter "DisplayName eq '$($assignment.Identity)'"
$PrincipalIdValue = $group.Id
}

$bodyParam = @{
principalId = $PrincipalIdValue
resourceId = $currentAADServicePrincipal.ObjectID
appRoleId = "00000000-0000-0000-0000-000000000000"
}
Write-Verbose -Message "Adding member {$($member.InputObject.ToString())}"
New-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $currentAADServicePrincipal.ObjectID `
-BodyParameter $bodyParam | Out-Null
}
}

if ($membersToRemove.Count -gt 0)
{
$AppRoleAssignedToValues = @()
foreach ($assignment in $currentAADServicePrincipal.AppRoleAssignedTo)
{
$AppRoleAssignedToValues += @{
PrincipalType = $assignment.PrincipalType
Identity = $assignment.Identity
}
}
foreach ($member in $membersToRemove)
{
$assignment = $AppRoleAssignedToValues | Where-Object -FilterScript {$_.Identity -eq $member.InputObject}
if ($assignment.PrincipalType -eq 'User')
{
Write-Verbose -Message "Retrieving user {$($assignment.Identity)}"
$user = Get-MgUser -Filter "startswith(UserPrincipalName, '$($assignment.Identity)')"
$PrincipalIdValue = $user.Id
}
else
{
Write-Verbose -Message "Retrieving group {$($assignment.Identity)}"
$group = Get-MgGroup -Filter "DisplayName eq '$($assignment.Identity)'"
$PrincipalIdValue = $group.Id
}
Write-Verbose -Message "PrincipalID Value = '$PrincipalIdValue'"
Write-Verbose -Message "ServicePrincipalId = '$($currentAADServicePrincipal.ObjectID)'"
$allAssignments = Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $currentAADServicePrincipal.ObjectID
$assignmentToRemove = $allAssignments | Where-Object -FilterScript {$_.PrincipalId -eq $PrincipalIdValue}
Write-Verbose -Message "Removing member {$($member.InputObject.ToString())}"
Remove-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $currentAADServicePrincipal.ObjectID `
-AppRoleAssignmentId $assignmentToRemove.Id | Out-Null
}
}
}
}
}
# ServicePrincipal exists but should not
elseif ($Ensure -eq 'Absent' -and $currentAADServicePrincipal.Ensure -eq 'Present')
Expand All @@ -348,6 +471,10 @@ function Test-TargetResource
[System.String]
$AppId,

[Parameter()]
[Microsoft.Management.Infrastructure.CimInstance[]]
$AppRoleAssignedTo,

[Parameter()]
[System.String]
$ObjectId,
Expand Down Expand Up @@ -525,7 +652,10 @@ function Export-TargetResource
$i = 1
Write-Host "`r`n" -NoNewline
$Script:ExportMode = $true
[array] $Script:exportedInstances = Get-MgServicePrincipal -All:$true -Filter $Filter -ErrorAction Stop
[array] $Script:exportedInstances = Get-MgServicePrincipal -All:$true `
-Filter $Filter `
-Expand 'AppRoleAssignedTo' `
-ErrorAction Stop
foreach ($AADServicePrincipal in $Script:exportedInstances)
{
Write-Host " |---[$i/$($Script:exportedInstances.Count)] $($AADServicePrincipal.DisplayName)" -NoNewline
Expand All @@ -544,11 +674,20 @@ function Export-TargetResource
{
$Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode `
-Results $Results
if ($Results.AppRoleAssignedTo.Count -gt 0)
{
$Results.AppRoleAssignedTo = Get-M365DSCAzureADServicePrincipalAssignmentAsString -Assignments $Results.AppRoleAssignedTo
}
$currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName `
-ConnectionMode $ConnectionMode `
-ModulePath $PSScriptRoot `
-Results $Results `
-Credential $Credential
if ($null -ne $Results.AppRoleAssignedTo)
{
$currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock `
-ParameterName 'AppRoleAssignedTo'
}
$dscContent += $currentDSCBlock
Save-M365DSCPartialExport -Content $currentDSCBlock `
-FileName $Global:PartialExportFileName
Expand All @@ -573,4 +712,26 @@ function Export-TargetResource
}
}

function Get-M365DSCAzureADServicePrincipalAssignmentAsString
{
[CmdletBinding()]
[OutputType([System.String])]
param(
[Parameter(Mandatory = $true)]
[System.Collections.ArrayList]
$Assignments
)

$StringContent = '@('
foreach ($assignment in $Assignments)
{
$StringContent += "MSFT_AADServicePrincipalRoleAssignment {`r`n"
$StringContent += " PrincipalType = '" + $assignment.PrincipalType + "'`r`n"
$StringContent += " Identity = '" + $assignment.Identity + "'`r`n"
$StringContent += " }`r`n"
}
$StringContent += ' )'
return $StringContent
}

Export-ModuleMember -Function *-TargetResource
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
[ClassVersion("1.0.0")]
class MSFT_AADServicePrincipalRoleAssignment
{
[Write, Description("Type of principal. Accepted values are User or Group"), ValueMap{"Group","User"}, Values{"Group","User"}] String PrincipalType;
[Write, Description("Unique identity representing the principal.")] String Identity;
};

[ClassVersion("1.0.0.0"), FriendlyName("AADServicePrincipal")]
class MSFT_AADServicePrincipal : OMI_BaseResource
{
[Key, Description("The unique identifier for the associated application.")] String AppId;
[Write, Description("App role assignments for this app or service, granted to users, groups, and other service principals."), EmbeddedInstance("MSFT_AADServicePrincipalRoleAssignment")] String AppRoleAssignedTo[];
[Write, Description("The ObjectID of the ServicePrincipal")] String ObjectID;
[Write, Description("Displayname of the ServicePrincipal.")] String DisplayName;
[Write, Description("The alternative names for this service principal")] String AlternativeNames[];
Expand Down
Loading

0 comments on commit b2ccc65

Please sign in to comment.