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

Org settings Installation Options #3365

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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