Skip to content

Commit

Permalink
Merge pull request #3365 from NikCharlebois/OrgSettingsAddServicePrin…
Browse files Browse the repository at this point in the history
…cipal

Org settings Installation Options
  • Loading branch information
NikCharlebois committed Jun 20, 2023
2 parents ebf7108 + cad0e03 commit f627adf
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
FIXES [#3217](https://github.com/microsoft/Microsoft365DSC/issues/3217)
* O365OrgSettings
* Added support for the PlannerAllowCalendarSharing property for Planner.
* Added support for the Microsoft 365 installation options.
* SCProtectionAlert
* Prevents extracting system rules.
FIXES [#3224](https://github.com/microsoft/Microsoft365DSC/issues/3224)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ function Get-TargetResource
[System.Boolean]
$AdminCenterReportDisplayConcealedNames,

[Parameter()]
[System.String]
[ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')]
$InstallationOptionsUpdateChannel,

[Parameter()]
[System.String[]]
[ValidateSet('isVisioEnabled', 'isSkypeForBusinessEnabled', 'isProjectEnabled', 'isMicrosoft365AppsEnabled')]
$InstallationOptionsAppsForWindows,

[Parameter()]
[System.String[]]
[ValidateSet('isSkypeForBusinessEnabled', 'isMicrosoft365AppsEnabled')]
$InstallationOptionsAppsForMac,

[Parameter()]
[ValidateSet('Present', 'Absent')]
[System.String]
Expand Down Expand Up @@ -57,9 +72,9 @@ function Get-TargetResource

$ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' `
-InboundParameters $PSBoundParameters `
-ProfileName 'v1.0'
-ProfileName 'beta'

$ConnectionMode = New-M365DSCConnection -Workload 'Tasks' `
$ConnectionModeTasks = New-M365DSCConnection -Workload 'Tasks' `
-InboundParameters $PSBoundParameters

#Ensure the proper dependencies are installed in the current environment.
Expand Down Expand Up @@ -89,14 +104,50 @@ function Get-TargetResource
$CortanaId = '0a0a29f9-0a25-49c7-94bf-c53c3f8fa69d'
$CortanaEnabledValue = Get-MgServicePrincipal -Filter "appId eq '$CortanaId'" -Property 'AccountEnabled'

$MRODeviceManagerService = 'ebe0c285-db95-403f-a1a3-a793bd6d7767'
try
{
$servicePrincipal = Get-MgServicePrincipal -Filter "appid eq 'ebe0c285-db95-403f-a1a3-a793bd6d7767'"
if ($null -eq $servicePrincipal)
{
Write-Verbose -Message "Registering the MRO Device Manager Service Principal"
New-MgServicePrincipal -AppId 'ebe0c285-db95-403f-a1a3-a793bd6d7767' -ErrorAction Stop | Out-Null
}
}
catch
{
Write-Verbose -Message $_
}

$AdminCenterReportDisplayConcealedNamesValue = Get-M365DSCOrgSettingsAdminCenterReport

$installationOptions = Get-M365DSCOrgSettingsInstallationOptions -AuthenticationOption $ConnectionModeTasks
$appsForWindowsValue = @()
foreach ($key in $installationOptions.appsForWindows.Keys)
{
if ($installationOptions.appsForWindows.$key)
{
$appsForWindowsValue += $key
}
}
$appsForMacValue = @()
foreach ($key in $installationOptions.appsForMac.Keys)
{
if ($installationOptions.appsForMac.$key)
{
$appsForMacValue += $key
}
}

return @{
IsSingleInstance = 'Yes'
CortanaEnabled = $CortanaEnabledValue.AccountEnabled
M365WebEnableUsersToOpenFilesFrom3PStorage = $M365WebEnableUsersToOpenFilesFrom3PStorageValue.AccountEnabled
PlannerAllowCalendarSharing = $PlannerSettings.allowCalendarSharing
AdminCenterReportDisplayConcealedNames = $AdminCenterReportDisplayConcealedNamesValue.displayConcealedNames
InstallationOptionsUpdateChannel = $installationOptions.updateChannel
InstallationOptionsAppsForWindows = $appsForWindowsValue
InstallationOptionsAppsForMac = $appsForMacValue
Credential = $Credential
ApplicationId = $ApplicationId
TenantId = $TenantId
Expand Down Expand Up @@ -143,6 +194,21 @@ function Set-TargetResource
[System.Boolean]
$AdminCenterReportDisplayConcealedNames,

[Parameter()]
[System.String]
[ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')]
$InstallationOptionsUpdateChannel,

[Parameter()]
[System.String[]]
[ValidateSet('isVisioEnabled', 'isSkypeForBusinessEnabled', 'isProjectEnabled', 'isMicrosoft365AppsEnabled')]
$InstallationOptionsAppsForWindows,

[Parameter()]
[System.String[]]
[ValidateSet('isSkypeForBusinessEnabled', 'isMicrosoft365AppsEnabled')]
$InstallationOptionsAppsForMac,

[Parameter()]
[ValidateSet('Present', 'Absent')]
[System.String]
Expand Down Expand Up @@ -190,7 +256,6 @@ function Set-TargetResource
Add-M365DSCTelemetryEvent -Data $data
#endregion


Write-Verbose -Message 'Setting configuration of Office 365 Settings'
$currentValues = Get-TargetResource @PSBoundParameters

Expand All @@ -210,7 +275,8 @@ function Set-TargetResource

$CortanaId = '0a0a29f9-0a25-49c7-94bf-c53c3f8fa69d'
$CortanaEnabledValue = Get-MgServicePrincipal -Filter "appId eq '$CortanaId'" -Property 'AccountEnabled, Id'
if ($CortanaEnabled -ne $CortanaEnabledValue.AccountEnabled)
if ($CortanaEnabled -ne $CortanaEnabledValue.AccountEnabled -and `
$CortanaEnabledValue.Id -ne $null)
{
Write-Verbose -Message "Updating the Cortana setting to {$CortanaEnabled}"
Update-MgServicePrincipal -ServicePrincipalId $($CortanaEnabledValue.Id) `
Expand All @@ -224,6 +290,67 @@ function Set-TargetResource
Write-Verbose -Message "Updating the Admin Center Report Display Concealed Names setting to {$AdminCenterReportDisplayConcealedNames}"
Update-M365DSCOrgSettingsAdminCenterReport -DisplayConcealedNames $AdminCenterReportDisplayConcealedNames
}

if ($PSBoundParameters.ContainsKey("InstallationOptionsAppsForWindows") -or $PSBoundParameters.ContainsKey("InstallationOptionsAppsForMac"))
{
$ConnectionModeTasks = New-M365DSCConnection -Workload 'Tasks' `
-InboundParameters $PSBoundParameters
$InstallationOptions = Get-M365DSCOrgSettingsInstallationOptions -AuthenticationOption $ConnectionModeTasks
$InstallationOptionsToUpdate = @{
updateChannel = ""
appsForWindows = @{
isMicrosoft365AppsEnabled = $false
isProjectEnabled = $false
isSkypeForBusinessEnabled = $false
isVisioEnabled = $false
}
appsForMac = @{
isMicrosoft365AppsEnabled = $false
isSkypeForBusinessEnabled = $false
}
}

if ($PSBoundParameters.ContainsKey("InstallationOptionsUpdateChannel") -and `
($InstallationOptionsUpdateChannel -ne $InstallationOptions.updateChannel))
{
$InstallationOptionsToUpdate.updateChannel = $InstallationOptionsUpdateChannel
}
else
{
$InstallationOptionsToUpdate.Remove('updateChannel') | Out-Null
}

if ($PSBoundParameters.ContainsKey("InstallationOptionsAppsForWindows"))
{
foreach ($key in $InstallationOptionsAppsForWindows)
{
$InstallationOptionsToUpdate.appsForWindows.$key = $true
}
}
else
{
$InstallationOptionsToUpdate.Remove('appsForWindows') | Out-Null
}

if ($PSBoundParameters.ContainsKey("InstallationOptionsAppsForMac"))
{
foreach ($key in $InstallationOptionsAppsForMac)
{
$InstallationOptionsToUpdate.appsForMac.$key = $true
}
}
else
{
$InstallationOptionsToUpdate.Remove('appsForMac') | Out-Null
}

if ($InstallationOptionsToUpdate.Keys.Count -gt 0)
{
Write-Verbose -Message "Updating O365 Installation Options with $(Convert-M365DscHashtableToString -Hashtable $InstallationOptionsToUpdate)"
Update-M365DSCOrgSettingsInstallationOptions -Options $InstallationOptionsToUpdate `
-AuthenticationOption $ConnectionModeTasks
}
}
}

function Test-TargetResource
Expand Down Expand Up @@ -253,6 +380,21 @@ function Test-TargetResource
[System.Boolean]
$AdminCenterReportDisplayConcealedNames,

[Parameter()]
[System.String]
[ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')]
$InstallationOptionsUpdateChannel,

[Parameter()]
[System.String[]]
[ValidateSet('isVisioEnabled', 'isSkypeForBusinessEnabled', 'isProjectEnabled', 'isMicrosoft365AppsEnabled')]
$InstallationOptionsAppsForWindows,

[Parameter()]
[System.String[]]
[ValidateSet('isSkypeForBusinessEnabled', 'isMicrosoft365AppsEnabled')]
$InstallationOptionsAppsForMac,

[Parameter()]
[ValidateSet('Present', 'Absent')]
[System.String]
Expand Down Expand Up @@ -344,7 +486,7 @@ function Export-TargetResource
)
$ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' `
-InboundParameters $PSBoundParameters `
-ProfileName 'v1.0'
-ProfileName 'beta'

#Ensure the proper dependencies are installed in the current environment.
Confirm-M365DSCDependencies
Expand Down Expand Up @@ -464,4 +606,69 @@ function Update-M365DSCOrgSettingsAdminCenterReport
Invoke-MgGraphRequest -Method PATCH -Uri $url -Body $body | Out-Null
}

function Get-M365DSCOrgSettingsInstallationOptions
{
[CmdletBinding()]
[OutputType([System.Collections.Hashtable])]
param(
[Parameter(Mandatory = $true)]
[System.String]
$AuthenticationOption
)

try
{
$url = 'https://graph.microsoft.com/beta/admin/microsoft365Apps/installationOptions'
$results = Invoke-MgGraphRequest -Method GET -Uri $url
}
catch
{
if ($_.Exception.ToString().Contains('Forbidden (Forbidden)'))
{
if ($AuthenticationOption -eq 'Credentials')
{
$errorMessage = "You don't have the proper permissions to retrieve the Office 365 Apps Installation Options." `
+ " When using Credentials to authenticate, you need to grant permissions to the Microsoft Graph PowerShell SDK by running" `
+ " Connect-MgGraph -Scopes OrgSettings-Microsoft365Install.Read.All"
Write-Error -Message $errorMessage
}
}
}
return $results
}

function Update-M365DSCOrgSettingsInstallationOptions
{
[CmdletBinding()]
[OutputType([Void])]
param(
[Parameter(Mandatory = $true)]
[System.Collections.Hashtable]
$Options,

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

try
{
$url = 'https://graph.microsoft.com/beta/admin/microsoft365Apps/installationOptions'
Invoke-MgGraphRequest -Method PATCH -Uri $url -Body $Options | Out-Null
}
catch
{
if ($_.Exception.ToString().Contains('Forbidden (Forbidden)'))
{
if ($AuthenticationOption -eq 'Credentials')
{
$errorMessage = "You don't have the proper permissions to retrieve the Office 365 Apps Installation Options." `
+ " When using Credentials to authenticate, you need to grant permissions to the Microsoft Graph PowerShell SDK by running" `
+ " Connect-MgGraph -Scopes OrgSettings-Microsoft365Install.ReadWrite.All"
Write-Error -Message $errorMessage
}
}
}
}

Export-ModuleMember -Function *-TargetResource
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ class MSFT_O365OrgSettings : OMI_BaseResource
[Write, Description("Let users open files stored in third-party storage services in Microsoft 365 on the Web.")] Boolean M365WebEnableUsersToOpenFilesFrom3PStorage;
[Write, Description("Allow Planner users to publish their plans and assigned tasks to Outlook or other calendars through iCalendar feeds.")] Boolean PlannerAllowCalendarSharing;
[Write, Description("Controls whether or not the Admin Center reports will conceale user, group and site names.")] Boolean AdminCenterReportDisplayConcealedNames;
[Write, Description("Defines how often you want your users to get feature updates for Microsoft 365 apps installed on devices running Windows"), ValueMap{"current","monthlyEnterprise","semiAnnual"}, Values{"current","monthlyEnterprise","semiAnnual"}] String InstallationOptionsUpdateChannel;
[Write, Description("Defines the apps users can install on Windows and mobile devices."), ValueMap{"isVisioEnabled","isSkypeForBusinessEnabled","isProjectEnabled","isMicrosoft365AppsEnabled"}, Values{"isVisioEnabled","isSkypeForBusinessEnabled","isProjectEnabled","isMicrosoft365AppsEnabled"}] String InstallationOptionsAppsForWindows[];
[Write, Description("Defines the apps users can install on Mac devices."), ValueMap{"isSkypeForBusinessEnabled","isMicrosoft365AppsEnabled"}, Values{"isSkypeForBusinessEnabled","isMicrosoft365AppsEnabled"}] String InstallationOptionsAppsForMac[];
[Write, Description("Credentials of the Global 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;
Expand Down
7 changes: 6 additions & 1 deletion Tests/QA/Microsoft365DSC.SettingsJson.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ Describe -Name 'Successfully validate all used permissions in Settings.json file
$settings = ConvertFrom-Json -InputObject $json
foreach ($permission in $settings.permissions.graph.delegated.read)
{
$permission.Name | Should -BeIn $allPermissions
# Only validate non-GUID (hidden) permissions.
$ObjectGuid = [System.Guid]::empty
if (-not [System.Guid]::TryParse($permission.Name ,[System.Management.Automation.PSReference]$ObjectGuid))
{
$permission.Name | Should -BeIn $allPermissions
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture {
}
}

Mock -CommandName Get-M365DSCOrgSettingsInstallationOptions -MockWith {
return @{
'@odata.context' = 'https://graph.microsoft.com/beta/$metadata#admin/microsoft365Apps/installationOptions/$entity'
updateChannel = 'current'
appsForMac = @{
isSkypeForBusinessEnabled = $True
isMicrosoft365AppsEnabled = $true
}
appsForWindows = @{
isVisioEnabled = $True
isSkypeForBusinessEnabled = $False
isMicrosoft365AppsEnabled = $true
isProjectEnabled = $true
}
}
}

Mock -CommandName Get-M365DSCO365OrgSettingsPlannerConfig -MockWith {
return @{
allowCalendarSharing = $false
Expand All @@ -60,6 +77,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture {
AdminCenterReportDisplayConcealedNames = $True;
IsSingleInstance = 'Yes'
M365WebEnableUsersToOpenFilesFrom3PStorage = $False;
InstallationOptionsAppsForMac = @('isSkypeForBusinessEnabled', 'isMicrosoft365AppsEnabled')
InstallationOptionsAppsForWindows = @('isVisioEnabled', 'isMicrosoft365AppsEnabled', 'isProjectEnabled')
InstallationOptionsUpdateChannel = 'current'
PlannerAllowCalendarSharing = $False
Credential = $Credential
}
Expand Down

0 comments on commit f627adf

Please sign in to comment.