From 357c18ed0b4b02975056f3638544be721406acbf Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Wed, 9 Oct 2024 20:08:05 -0700 Subject: [PATCH 01/32] update parameters and filter --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 1231 +++++++++++++++++ ...MobileAppsWindowsOfficeSuiteApp.schema.mof | 14 + .../readme.md | 6 + .../settings.json | 32 + .../1-Create.ps1 | 26 + .../2-Update.ps1 | 26 + .../3-Remove.ps1 | 26 + ...eMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 178 +++ 8 files changed, 1539 insertions(+) create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/readme.md create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/settings.json create mode 100644 Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 create mode 100644 Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 create mode 100644 Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 create mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 new file mode 100644 index 0000000000..f616acf07a --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -0,0 +1,1231 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + #region Intune resource parameters + + [Parameter()] + [System.String] + $Id, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + $Publisher, + + [Parameter()] + [System.Boolean] + $IsFeatured, + + [Parameter()] + [System.String] + $PrivacyInformationUrl, + + [Parameter()] + [System.String] + $InformationUrl, + + [Parameter()] + [System.String] + $Owner, + + [Parameter()] + [System.String] + $Developer, + + [Parameter()] + [System.String] + $Notes, + + [Parameter()] + [System.String] + [ValidateSet('notPublished', 'processing','published')] + $PublishingState, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.Boolean] + $AutoAcceptEula, + + [Parameter()] + [System.String[]] + $ProductIds, + + [Parameter()] + [PSCustomObject] + $ExcludedApps, + + [Parameter()] + [System.Boolean] + $UseSharedComputerActivation, + + [Parameter()] + [System.String] + [ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')] + $UpdateChannel = 'monthlyEnterprise', + + [Parameter()] + [System.String] + [ValidateSet('officeOpenDocumentFormat', 'binaryFormat')] + $OfficeSuiteAppDefaultFileFormat, + + [Parameter()] + [System.String] + [ValidateSet('x86', 'x64')] + $OfficePlatformArchitecture = 'x64', + + [Parameter()] + [System.String[]] + $LocalesToInstall, + + [Parameter()] + [System.String] + [ValidateSet('none', 'full')] + $InstallProgressDisplayLevel = 'none', + + [Parameter()] + [System.Boolean] + $ShouldUninstallOlderVersionsOfOffice = $true, + + [Parameter()] + [System.String] + $TargetVersion = "", +> + [Parameter()] + [System.String] + $UpdateVersion = "", + + [Parameter()] + [System.Byte[]] + $OfficeConfigurationXml, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Categories, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $LargeIcon, + + #endregion + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -InboundParameters $PSBoundParameters | Out-Null + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $nullResult = $PSBoundParameters + $nullResult.Ensure = 'Absent' + try + { + $instance = Get-MgBetaDeviceAppManagementMobileApp ` + -Filter "(isof('microsoft.graph.officeSuiteApp') and displayName eq '$DisplayName')" ` + -ExpandProperty "categories,assignments" ` + -ErrorAction SilentlyContinue | Where-Object ` + -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.officeSuiteApp' } + + if ($null -eq $instance) + { + Write-Verbose -Message "No Mobile app with DisplayName {$DisplayName} was found. Search with DisplayName." + $instance = Get-MgBetaDeviceAppManagementMobileApp ` + -MobileAppId $Id ` + -ExpandProperty "categories,assignments" ` + -ErrorAction Stop | Where-Object ` + -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.officeSuiteApp' } + } + + if ($null -eq $instance) + { + Write-Verbose -Message "No Mobile app with {$Id} was found." + return $nullResult + } + + $results = @{ + Id = $instance.Id + Description = $instance.Description + Developer = $instance.Developer + DisplayName = $instance.DisplayName + InformationUrl = $instance.InformationUrl + IsFeatured = $instance.IsFeatured + Notes = $instance.Notes + Owner = $instance.Owner + PrivacyInformationUrl = $instance.PrivacyInformationUrl + Publisher = $instance.Publisher + PublishingState = $instance.PublishingState.ToString() + RoleScopeTagIds = $instance.RoleScopeTagIds + BundleId = $instance.BundleId + BuildNumber = $instance.BuildNumber + VersionNumber = $instance.VersionNumber + IgnoreVersionDetection = $instance.AdditionalProperties.ignoreVersionDetection + + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ApplicationSecret = $ApplicationSecret + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + #region complex types + + #Categories + if($null -ne $instance.Categories) + { + $results.Add('Categories', $instance.Categories) + } + else { + $results.Add('Categories', "") + } + + #childApps + if($null -ne $instance.AdditionalProperties.childApps) + { + $results.Add('ChildApps', $instance.AdditionalProperties.childApps) + } + else { + $results.Add('ChildApps', "") + } + + #Assignments + $resultAssignments = @() + $appAssignments = Get-MgBetaDeviceAppManagementMobileAppAssignment -MobileAppId $instance.Id + if ($null -ne $appAssignments -and $appAssignments.count -gt 0) + { + $resultAssignments += ConvertFrom-IntuneMobileAppAssignment ` + -IncludeDeviceFilter:$true ` + -Assignments ($appAssignments) + + $results.Add('Assignments', $resultAssignments) + } + + #LargeIcon + # The large is returned only when Get cmdlet is called with Id parameter. The large icon is a base64 encoded string, so we need to convert it to a byte array. + $instanceWithLargeIcon = Get-MgBetaDeviceAppManagementMobileApp -MobileAppId $instance.Id + if($null -ne $instanceWithLargeIcon.LargeIcon) + { + $results.Add('LargeIcon', $instanceWithLargeIcon.LargeIcon) + } + else { + $results.Add('LargeIcon', "") + } + + #end region complex types + + return [System.Collections.Hashtable] $results + } + catch + { + Write-Verbose -Message $_ + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullResult + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + #region Intune resource parameters + + [Parameter()] + [System.String] + $Id, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + $Publisher, + + [Parameter()] + [System.Boolean] + $IsFeatured, + + [Parameter()] + [System.String] + $PrivacyInformationUrl, + + [Parameter()] + [System.String] + $InformationUrl, + + [Parameter()] + [System.String] + $Owner, + + [Parameter()] + [System.String] + $Developer, + + [Parameter()] + [System.String] + $Notes, + + [Parameter()] + [System.String] + [ValidateSet('notPublished', 'processing','published')] + $PublishingState, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.Boolean] + $AutoAcceptEula, + + [Parameter()] + [System.String[]] + $ProductIds, + + [Parameter()] + [PSCustomObject] + $ExcludedApps, + + [Parameter()] + [System.Boolean] + $UseSharedComputerActivation, + + [Parameter()] + [System.String] + [ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')] + $UpdateChannel = 'monthlyEnterprise', + + [Parameter()] + [System.String] + [ValidateSet('officeOpenDocumentFormat', 'binaryFormat')] + $OfficeSuiteAppDefaultFileFormat, + + [Parameter()] + [System.String] + [ValidateSet('x86', 'x64')] + $OfficePlatformArchitecture = 'x64', + + [Parameter()] + [System.String[]] + $LocalesToInstall, + + [Parameter()] + [System.String] + [ValidateSet('none', 'full')] + $InstallProgressDisplayLevel = 'none', + + [Parameter()] + [System.Boolean] + $ShouldUninstallOlderVersionsOfOffice = $true, + + [Parameter()] + [System.String] + $TargetVersion = "", +> + [Parameter()] + [System.String] + $UpdateVersion = "", + + [Parameter()] + [System.Byte[]] + $OfficeConfigurationXml, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Categories, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $LargeIcon, + + #endregion + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $currentInstance = Get-TargetResource @PSBoundParameters + $PSBoundParameters.Remove('Ensure') | Out-Null + $PSBoundParameters.Remove('Credential') | Out-Null + $PSBoundParameters.Remove('ApplicationId') | Out-Null + $PSBoundParameters.Remove('ApplicationSecret') | Out-Null + $PSBoundParameters.Remove('TenantId') | Out-Null + $PSBoundParameters.Remove('CertificateThumbprint') | Out-Null + $PSBoundParameters.Remove('ManagedIdentity') | Out-Null + $PSBoundParameters.Remove('AccessTokens') | Out-Null + + $CreateParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + + # CREATE + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + Write-Host "Create MacOS app: $DisplayName" + + $CreateParameters = ([Hashtable]$PSBoundParameters).clone() + $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters + + $AdditionalProperties = Get-M365DSCIntuneMobileMocOSLobAppAdditionalProperties -Properties ($CreateParameters) + foreach ($key in $AdditionalProperties.keys) + { + if ($key -ne '@odata.type') + { + $keyName = $key.substring(0, 1).ToUpper() + $key.substring(1, $key.length - 1) + $CreateParameters.remove($keyName) + } + } + + $CreateParameters.remove('Id') | Out-Null + $CreateParameters.remove('Ensure') | Out-Null + $CreateParameters.remove('Categories') | Out-Null + $CreateParameters.remove('Assignments') | Out-Null + $CreateParameters.remove('childApps') | Out-Null + $CreateParameters.remove('IgnoreVersionDetection') | Out-Null + $CreateParameters.Remove('Verbose') | Out-Null + $CreateParameters.Remove('PublishingState') | Out-Null #Not allowed to update as it's a computed property + $CreateParameters.Remove('LargeIcon') | Out-Null + + foreach ($key in ($CreateParameters.clone()).Keys) + { + if ($CreateParameters[$key].getType().Fullname -like '*CimInstance*') + { + $CreateParameters[$key] = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $CreateParameters[$key] + } + } + + if ($AdditionalProperties) + { + $CreateParameters.add('AdditionalProperties', $AdditionalProperties) + } + + #LargeIcon + if($LargeIcon) + { + [System.Object]$LargeIconValue = ConvertTo-M365DSCIntuneAppLargeIcon -LargeIcon $LargeIcon + $CreateParameters.Add('LargeIcon', $LargeIconValue) + } + + $app = New-MgBetaDeviceAppManagementMobileApp @CreateParameters + + #Assignments + $assignmentsHash = ConvertTo-IntuneMobileAppAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + if ($app.id) + { + Update-MgBetaDeviceAppManagementMobileAppAssignment -MobileAppId $app.id ` + -Target $assignmentsHash ` + -Repository 'deviceAppManagement/mobileAppAssignments' + } + } + # UPDATE + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + Write-Host "Update MacOS app: $DisplayName" + + $PSBoundParameters.Remove('Assignments') | Out-Null + $UpdateParameters = ([Hashtable]$PSBoundParameters).clone() + $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters + + $AdditionalProperties = Get-M365DSCIntuneMobileMocOSLobAppAdditionalProperties -Properties ($UpdateParameters) + foreach ($key in $AdditionalProperties.keys) + { + if ($key -ne '@odata.type') + { + $keyName = $key.substring(0, 1).ToUpper() + $key.substring(1, $key.length - 1) + #Remove additional keys, so that later they can be added as 'AdditionalProperties' + $UpdateParameters.Remove($keyName) + } + } + + $UpdateParameters.Remove('Id') | Out-Null + $UpdateParameters.Remove('Verbose') | Out-Null + $UpdateParameters.Remove('Categories') | Out-Null + $UpdateParameters.Remove('PublishingState') | Out-Null #Not allowed to update as it's a computed property + + foreach ($key in ($UpdateParameters.clone()).Keys) + { + if ($UpdateParameters[$key].getType().Fullname -like '*CimInstance*') + { + $value = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $UpdateParameters[$key] + $UpdateParameters[$key] = $value + } + } + + if ($AdditionalProperties) + { + $UpdateParameters.Add('AdditionalProperties', $AdditionalProperties) + } + + #LargeIcon + if($LargeIcon) + { + [System.Object]$LargeIconValue = ConvertTo-M365DSCIntuneAppLargeIcon -LargeIcon $LargeIcon + $UpdateParameters.Add('LargeIcon', $LargeIconValue) + } + + Update-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id @UpdateParameters + Write-Host "Updated MacOS App: $DisplayName." + + #Assignments + $assignmentsHash = ConvertTo-IntuneMobileAppAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + Update-MgBetaDeviceAppManagementMobileAppAssignment -MobileAppId $currentInstance.id ` + -Target $assignmentsHash ` + -Repository 'deviceAppManagement/mobileAppAssignments' + } + # REMOVE + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + Write-Host "Remove MacOS app: $DisplayName" + Remove-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id -Confirm:$false + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + #region Intune resource parameters + + [Parameter()] + [System.String] + $Id, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + $Publisher, + + [Parameter()] + [System.Boolean] + $IsFeatured, + + [Parameter()] + [System.String] + $PrivacyInformationUrl, + + [Parameter()] + [System.String] + $InformationUrl, + + [Parameter()] + [System.String] + $Owner, + + [Parameter()] + [System.String] + $Developer, + + [Parameter()] + [System.String] + $Notes, + + [Parameter()] + [System.String] + [ValidateSet('notPublished', 'processing','published')] + $PublishingState, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.Boolean] + $AutoAcceptEula, + + [Parameter()] + [System.String[]] + $ProductIds, + + [Parameter()] + [PSCustomObject] + $ExcludedApps, + + [Parameter()] + [System.Boolean] + $UseSharedComputerActivation, + + [Parameter()] + [System.String] + [ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')] + $UpdateChannel = 'monthlyEnterprise', + + [Parameter()] + [System.String] + [ValidateSet('officeOpenDocumentFormat', 'binaryFormat')] + $OfficeSuiteAppDefaultFileFormat, + + [Parameter()] + [System.String] + [ValidateSet('x86', 'x64')] + $OfficePlatformArchitecture = 'x64', + + [Parameter()] + [System.String[]] + $LocalesToInstall, + + [Parameter()] + [System.String] + [ValidateSet('none', 'full')] + $InstallProgressDisplayLevel = 'none', + + [Parameter()] + [System.Boolean] + $ShouldUninstallOlderVersionsOfOffice = $true, + + [Parameter()] + [System.String] + $TargetVersion = "", +> + [Parameter()] + [System.String] + $UpdateVersion = "", + + [Parameter()] + [System.Byte[]] + $OfficeConfigurationXml, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Categories, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $LargeIcon, + + #endregion + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + Write-Verbose -Message "Testing configuration of Intune Mobile MacOS App: {$DisplayName}" + + $CurrentValues = Get-TargetResource @PSBoundParameters + if (-not (Test-M365DSCAuthenticationParameter -BoundParameters $CurrentValues)) + { + Write-Verbose "An error occured in Get-TargetResource, the app {$displayName} will not be processed" + throw "An error occured in Get-TargetResource, the app {$displayName} will not be processed. Refer to the event viewer logs for more information." + } + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck + $ValuesToCheck.Remove('Id') | Out-Null + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + + if ($CurrentValues.Ensure -ne $Ensure) + { + Write-Verbose -Message "Test-TargetResource returned $false" + return $false + } + $testResult = $true + + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) + { + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($source.getType().Name -like '*CimInstance*') + { + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + + if (-Not $testResult) + { + $testResult = $false + break + } + + $ValuesToCheck.Remove($key) | Out-Null + } + } + + if ($testResult) + { + $TestResult = Test-M365DSCParameterState -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()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -InboundParameters $PSBoundParameters + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + try + { + $Script:ExportMode = $true + [array] $Script:getInstances = Get-MgBetaDeviceAppManagementMobileApp ` + -Filter "isof('microsoft.graph.officeSuiteApp')" ` + -ExpandProperty "categories,assignments" ` + -ErrorAction Stop | Where-Object ` + -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.officeSuiteApp' } + + $i = 1 + $dscContent = '' + if ($Script:getInstances.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + + foreach ($config in $Script:getInstances) + { + if ($null -ne $Global:M365DSCExportResourceInstancesCount) + { + $Global:M365DSCExportResourceInstancesCount++ + } + + $displayedKey = $config.Id + Write-Host " |---[$i/$($Script:getInstances.Count)] $displayedKey" -NoNewline + + $params = @{ + Id = $config.Id + DisplayName = $config.DisplayName + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ApplicationSecret = $ApplicationSecret + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + $Results = Get-TargetResource @params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + + if (-not (Test-M365DSCAuthenticationParameter -BoundParameters $Results)) + { + Write-Verbose "An error occured in Get-TargetResource, the app {$($params.displayName)} will not be processed." + throw "An error occured in Get-TargetResource, the app {$($params.displayName)} will not be processed. Refer to the event viewer logs for more information." + } + + #region complex types + + #Categories + if($null -ne $Results.Categories) + { + $Results.Categories = Get-M365DSCIntuneAppCategoriesAsString -Categories $Results.Categories + } + else { + $Results.Remove('Categories') | Out-Null + } + + #ChildApps + if($null -ne $Results.childApps) + { + $Results.childApps = Get-M365DSCIntuneAppChildAppsAsString -ChildApps $Results.childApps + } + else { + $Results.Remove('childApps') | Out-Null + } + + #Assignments + if ($null -ne $Results.Assignments) + { + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject ([Array]$Results.Assignments) -CIMInstanceName DeviceManagementMobileAppAssignment + + if ($complexTypeStringResult) + { + $Results.Assignments = $complexTypeStringResult + } + else + { + $Results.Remove('Assignments') | Out-Null + } + } + + #LargeIcon + if($null -ne $Results.LargeIcon) + { + $Results.LargeIcon = Get-M365DSCIntuneAppLargeIconAsString -LargeIcon $Results.LargeIcon + } + else + { + $Results.Remove('LargeIcon') | Out-Null + } + + #endregion complex types + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + + #region complex types + + #Categories + if ($null -ne $Results.Categories) + { + $isCIMArray = $false + if ($Results.Categories.getType().Fullname -like '*[[\]]') + { + $isCIMArray = $true + } + + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Categories' -IsCIMArray:$isCIMArray + } + + #ChildApps + if ($null -ne $Results.childApps) + { + $isCIMArray = $false + if ($Results.childApps.getType().Fullname -like '*[[\]]') + { + $isCIMArray = $true + } + + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ChildApps' -IsCIMArray:$isCIMArray + } + + #Assignments + if ($null -ne $Results.Assignments) + { + $isCIMArray = $false + if ($Results.Assignments.getType().Fullname -like '*[[\]]') + { + $isCIMArray = $true + } + + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Assignments' -IsCIMArray:$isCIMArray + } + + #LargeIcon + if ($null -ne $Results.LargeIcon) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'LargeIcon' -IsCIMArray:$false + } + + #endregion complex types + + $dscContent += $currentDSCBlock + Save-M365DSCPartialExport -Content $currentDSCBlock ` + -FileName $Global:PartialExportFileName + $i++ + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + + return $dscContent + } + catch + { + Write-Host $Global:M365DSCEmojiRedX + + New-M365DSCLogEntry -Message 'Error during Export:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return '' + } +} + +#region Helper functions + +function Get-M365DSCIntuneAppCategoriesAsString +{ + [CmdletBinding()] + [OutputType([System.String])] + param( + [Parameter(Mandatory = $true)] + [System.Object[]] + $Categories + ) + + $StringContent = '@(' + $space = ' ' + $indent = ' ' + + $i = 1 + foreach ($category in $Categories) + { + if ($Categories.Count -gt 1) + { + $StringContent += "`r`n" + $StringContent += "$space" + } + + #Only export the displayName, not Id + $StringContent += "MSFT_DeviceManagementMobileAppCategory { `r`n" + $StringContent += "$($space)$($indent)displayName = '" + $category.displayName + "'`r`n" + $StringContent += "$space}" + + $i++ + } + + $StringContent += ')' + + return $StringContent +} + +function Get-M365DSCIntuneAppChildAppsAsString +{ + [CmdletBinding()] + [OutputType([System.String])] + param( + [Parameter(Mandatory = $true)] + [System.Object[]] + $ChildApps + ) + + $StringContent = '@(' + $space = ' ' + $indent = ' ' + + $i = 1 + foreach ($childApp in $ChildApps) + { + if ($ChildApps.Count -gt 1) + { + $StringContent += "`r`n" + $StringContent += "$space" + } + + $StringContent += "MSFT_DeviceManagementMobileAppChildApp { `r`n" + $StringContent += "$($space)$($indent)bundleId = '" + $childApp.bundleId + "'`r`n" + $StringContent += "$($space)$($indent)buildNumber = '" + $childApp.buildNumber + "'`r`n" + $StringContent += "$($space)$($indent)versionNumber = '" + $childApp.versionNumber + "'`r`n" + $StringContent += "$space}" + + $i++ + } + + $StringContent += ')' + + return $StringContent +} + +function Get-M365DSCIntuneMobileMocOSLobAppAdditionalProperties +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = 'true')] + [System.Collections.Hashtable] + $Properties + ) + + $additionalProperties = @( + 'IgnoreVersionDetection' + 'ChildApps' + ) + + $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp' } + $cloneProperties = $Properties.clone() + foreach ($property in $cloneProperties.Keys) + { + if ($property -in $additionalProperties) + { + $propertyName = $property[0].ToString().ToLower() + $property.Substring(1, $property.Length - 1) + if ($properties.$property -and $properties.$property.getType().FullName -like '*CIMInstance*') + { + if ($properties.$property.getType().FullName -like '*[[\]]') + { + $array = @() + foreach ($item in $properties.$property) + { + $array += Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $item + + } + $propertyValue = $array + } + else + { + $propertyValue = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $properties.$property + } + + } + else + { + $propertyValue = $properties.$property + } + + $results.Add($propertyName, $propertyValue) + } + } + + if ($results.Count -eq 1) + { + return $null + } + return $results +} + +function Get-M365DSCIntuneAppLargeIconAsString #Get and Export +{ + [CmdletBinding()] + [OutputType([System.String])] + param( + [Parameter(Mandatory = $true)] + [System.Object] + $LargeIcon + ) + + $space = ' ' + $indent = ' ' + + if ($null -ne $LargeIcon.Value) + { + $StringContent += "`r`n" + $StringContent += "$space" + + $base64String = [System.Convert]::ToBase64String($LargeIcon.Value) # This exports the base64 string (blob) of the byte array, same as we see in Graph API response + + $StringContent += "MSFT_DeviceManagementMimeContent { `r`n" + $StringContent += "$($space)$($indent)type = '" + $LargeIcon.Type + "'`r`n" + $StringContent += "$($space)$($indent)value = '" + $base64String + "'`r`n" + $StringContent += "$space}" + } + + return $StringContent + } + +function ConvertTo-M365DSCIntuneAppLargeIcon #set +{ + [OutputType([System.Object])] + param( + [Parameter(Mandatory = $true)] + [System.Object] + $LargeIcon + ) + + $result = @{ + type = $LargeIcon.Type + value = $iconValue + } + + return $result +} + +#endregion Helper functions + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof new file mode 100644 index 0000000000..fe8aabccae --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof @@ -0,0 +1,14 @@ +[ClassVersion("1.0.0.0"), FriendlyName("ResourceName")] +class MSFT_ResourceName : OMI_BaseResource +{ + [Key, Description("")] String PrimaryKey; + [Write, Description("")] String OtherProperties; + + [Write, Description("Present ensures the instance exists, absent ensures it is removed."), ValueMap{"Absent","Present"}, Values{"Absent","Present"}] 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("Managed ID being used for authentication.")] Boolean ManagedIdentity; + [Write, Description("Access token used for authentication.")] String AccessTokens[]; +}; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/readme.md new file mode 100644 index 0000000000..32e0e7fb27 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/readme.md @@ -0,0 +1,6 @@ + +# ResourceName + +## Description + +##TODO - Provide a short description of what the resource is set to configure. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/settings.json new file mode 100644 index 0000000000..edf14b05e4 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/settings.json @@ -0,0 +1,32 @@ +{ + "resourceName": "ResourceName", + "description": "Description of what the resource is about.", + "roles": { + "read": [ + "Role" + ], + "update": [ + "Role" + ] + }, + "permissions": { + "graph": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [ + { + "name": "Permission for Monitoring and Export" + } + ], + "update": [ + { + "name": "Permission for deploying" + } + ] + } + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 new file mode 100644 index 0000000000..b516274848 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 @@ -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()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 new file mode 100644 index 0000000000..b516274848 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 @@ -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()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 new file mode 100644 index 0000000000..b516274848 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 @@ -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()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + + } +} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 new file mode 100644 index 0000000000..780e0f343d --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -0,0 +1,178 @@ +[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) + +$CurrentScriptPath = $PSCommandPath.Split('\') +$CurrentScriptName = $CurrentScriptPath[$CurrentScriptPath.Length -1] +$ResourceName = $CurrentScriptName.Split('.')[1] +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource $ResourceName -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 New-M365DSCConnection -MockWith { + return "Credentials" + } + + ##TODO - Mock any Remove/Set/New cmdlets + + # 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 instance should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + ##TODO - Add Parameters + Ensure = 'Present' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return $null + Mock -CommandName Get-Cmdlet -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 a new instance from the Set method' { + ##TODO - Replace the New-Cmdlet by the appropriate one + Set-TargetResource @testParams + Should -Invoke -CommandName New-Cmdlet -Exactly 1 + } + } + + Context -Name "The instance exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + ##TODO - Add Parameters + Ensure = 'Absent' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return an instance + Mock -CommandName Get-Cmdlet -MockWith { + return @{ + + } + } + } + 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 instance from the Set method' { + Set-TargetResource @testParams + ##TODO - Replace the Remove-Cmdlet by the appropriate one + Should -Invoke -CommandName Remove-Cmdlet -Exactly 1 + } + } + + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + ##TODO - Add Parameters + Ensure = 'Present' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return the desired values + Mock -CommandName Get-Cmdlet -MockWith { + return @{ + + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The instance exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + ##TODO - Add Parameters + Ensure = 'Present' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return a drift + Mock -CommandName Get-Cmdlet -MockWith { + return @{ + + } + } + } + + 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 + ##TODO - Replace the Update-Cmdlet by the appropriate one + Should -Invoke -CommandName Update-Cmdlet -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return an instance + Mock -CommandName Get-Cmdlet -MockWith { + return @{ + + } + } + } + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope From c2383dcaaefed4fc4d5e7396a97c59d2d7719476 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Wed, 9 Oct 2024 22:01:18 -0700 Subject: [PATCH 02/32] updated parameter types --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 114 ++++++++++-------- 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index f616acf07a..4cf91d3fc9 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -61,10 +61,11 @@ function Get-TargetResource [Parameter()] [System.String[]] + [ValidateSet('O365ProPlusRetail', 'O365BusinessRetail', 'VisioProRetail', 'ProjectProRetail')] $ProductIds, [Parameter()] - [PSCustomObject] + [Microsoft.Management.Infrastructure.CimInstance] $ExcludedApps, [Parameter()] @@ -73,18 +74,18 @@ function Get-TargetResource [Parameter()] [System.String] - [ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')] - $UpdateChannel = 'monthlyEnterprise', + [ValidateSet('None', 'Current', 'Deferred', 'FirstReleaseCurrent', 'FirstReleaseDeferred', 'MonthlyEnterprise')] + $UpdateChannel, [Parameter()] [System.String] - [ValidateSet('officeOpenDocumentFormat', 'binaryFormat')] + [ValidateSet('NotConfigured', 'OfficeOpenXMLFormat', 'OfficeOpenDocumentFormat', 'UnknownFutureValue')] $OfficeSuiteAppDefaultFileFormat, [Parameter()] [System.String] - [ValidateSet('x86', 'x64')] - $OfficePlatformArchitecture = 'x64', + [ValidateSet('None', 'X86', 'X64', 'Arm', 'Neutral', 'Arm64')] + $OfficePlatformArchitecture, [Parameter()] [System.String[]] @@ -92,20 +93,20 @@ function Get-TargetResource [Parameter()] [System.String] - [ValidateSet('none', 'full')] - $InstallProgressDisplayLevel = 'none', + [ValidateSet('None', 'Full')] + $InstallProgressDisplayLevel, [Parameter()] [System.Boolean] - $ShouldUninstallOlderVersionsOfOffice = $true, + $ShouldUninstallOlderVersionsOfOffice, [Parameter()] [System.String] - $TargetVersion = "", -> + $TargetVersion, + [Parameter()] [System.String] - $UpdateVersion = "", + $UpdateVersion, [Parameter()] [System.Byte[]] @@ -202,21 +203,30 @@ function Get-TargetResource $results = @{ Id = $instance.Id - Description = $instance.Description - Developer = $instance.Developer DisplayName = $instance.DisplayName - InformationUrl = $instance.InformationUrl + Description = $instance.Description + Publisher = $instance.Publisher IsFeatured = $instance.IsFeatured - Notes = $instance.Notes - Owner = $instance.Owner PrivacyInformationUrl = $instance.PrivacyInformationUrl - Publisher = $instance.Publisher + InformationUrl = $instance.InformationUrl + Owner = $instance.Owner + Developer = $instance.Developer + Notes = $instance.Notes PublishingState = $instance.PublishingState.ToString() RoleScopeTagIds = $instance.RoleScopeTagIds - BundleId = $instance.BundleId - BuildNumber = $instance.BuildNumber - VersionNumber = $instance.VersionNumber - IgnoreVersionDetection = $instance.AdditionalProperties.ignoreVersionDetection + ProductIds = $instance.ProductIds + ExcludedApps = $instance.ExcludedApps + UseSharedComputerActivation = $instance.UseSharedComputerActivation + UpdateChannel = $instance.UpdateChannel + OfficeSuiteAppDefaultFileFormat = $instance.OfficeSuiteAppDefaultFileFormat + OfficePlatformArchitecture = $instance.OfficePlatformArchitecture + LocalesToInstall = $instance.LocalesToInstall + InstallProgressDisplayLevel = $instance.InstallProgressDisplayLevel + ShouldUninstallOlderVersionsOfOffice = $instance.ShouldUninstallOlderVersionsOfOffice + TargetVersion = $instance.TargetVersion + UpdateVersion = $instance.UpdateVersion + OfficeConfigurationXml = $instance.OfficeConfigurationXml + AutoAcceptEula = $instance.AdditionalProperties.AutoAcceptEula Ensure = 'Present' Credential = $Credential @@ -350,10 +360,11 @@ function Set-TargetResource [Parameter()] [System.String[]] + [ValidateSet('O365ProPlusRetail', 'O365BusinessRetail', 'VisioProRetail', 'ProjectProRetail')] $ProductIds, [Parameter()] - [PSCustomObject] + [Microsoft.Management.Infrastructure.CimInstance] $ExcludedApps, [Parameter()] @@ -362,18 +373,18 @@ function Set-TargetResource [Parameter()] [System.String] - [ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')] - $UpdateChannel = 'monthlyEnterprise', + [ValidateSet('None', 'Current', 'Deferred', 'FirstReleaseCurrent', 'FirstReleaseDeferred', 'MonthlyEnterprise')] + $UpdateChannel, [Parameter()] [System.String] - [ValidateSet('officeOpenDocumentFormat', 'binaryFormat')] + [ValidateSet('NotConfigured', 'OfficeOpenXMLFormat', 'OfficeOpenDocumentFormat', 'UnknownFutureValue')] $OfficeSuiteAppDefaultFileFormat, [Parameter()] [System.String] - [ValidateSet('x86', 'x64')] - $OfficePlatformArchitecture = 'x64', + [ValidateSet('None', 'X86', 'X64', 'Arm', 'Neutral', 'Arm64')] + $OfficePlatformArchitecture, [Parameter()] [System.String[]] @@ -381,20 +392,20 @@ function Set-TargetResource [Parameter()] [System.String] - [ValidateSet('none', 'full')] - $InstallProgressDisplayLevel = 'none', + [ValidateSet('None', 'Full')] + $InstallProgressDisplayLevel, [Parameter()] [System.Boolean] - $ShouldUninstallOlderVersionsOfOffice = $true, + $ShouldUninstallOlderVersionsOfOffice, [Parameter()] [System.String] - $TargetVersion = "", -> + $TargetVersion, + [Parameter()] [System.String] - $UpdateVersion = "", + $UpdateVersion, [Parameter()] [System.Byte[]] @@ -475,7 +486,7 @@ function Set-TargetResource # CREATE if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') { - Write-Host "Create MacOS app: $DisplayName" + Write-Host "Create office suite app: $DisplayName" $CreateParameters = ([Hashtable]$PSBoundParameters).clone() $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters @@ -534,7 +545,7 @@ function Set-TargetResource # UPDATE elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') { - Write-Host "Update MacOS app: $DisplayName" + Write-Host "Update office suite app: $DisplayName" $PSBoundParameters.Remove('Assignments') | Out-Null $UpdateParameters = ([Hashtable]$PSBoundParameters).clone() @@ -578,7 +589,7 @@ function Set-TargetResource } Update-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id @UpdateParameters - Write-Host "Updated MacOS App: $DisplayName." + Write-Host "Updated office suite App: $DisplayName." #Assignments $assignmentsHash = ConvertTo-IntuneMobileAppAssignment -IncludeDeviceFilter:$true -Assignments $Assignments @@ -589,7 +600,7 @@ function Set-TargetResource # REMOVE elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') { - Write-Host "Remove MacOS app: $DisplayName" + Write-Host "Remove office suite app: $DisplayName" Remove-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id -Confirm:$false } } @@ -657,10 +668,11 @@ function Test-TargetResource [Parameter()] [System.String[]] + [ValidateSet('O365ProPlusRetail', 'O365BusinessRetail', 'VisioProRetail', 'ProjectProRetail')] $ProductIds, [Parameter()] - [PSCustomObject] + [Microsoft.Management.Infrastructure.CimInstance] $ExcludedApps, [Parameter()] @@ -669,18 +681,18 @@ function Test-TargetResource [Parameter()] [System.String] - [ValidateSet('current', 'monthlyEnterprise', 'semiAnnual')] - $UpdateChannel = 'monthlyEnterprise', + [ValidateSet('None', 'Current', 'Deferred', 'FirstReleaseCurrent', 'FirstReleaseDeferred', 'MonthlyEnterprise')] + $UpdateChannel, [Parameter()] [System.String] - [ValidateSet('officeOpenDocumentFormat', 'binaryFormat')] + [ValidateSet('NotConfigured', 'OfficeOpenXMLFormat', 'OfficeOpenDocumentFormat', 'UnknownFutureValue')] $OfficeSuiteAppDefaultFileFormat, [Parameter()] [System.String] - [ValidateSet('x86', 'x64')] - $OfficePlatformArchitecture = 'x64', + [ValidateSet('None', 'X86', 'X64', 'Arm', 'Neutral', 'Arm64')] + $OfficePlatformArchitecture, [Parameter()] [System.String[]] @@ -688,20 +700,20 @@ function Test-TargetResource [Parameter()] [System.String] - [ValidateSet('none', 'full')] - $InstallProgressDisplayLevel = 'none', + [ValidateSet('None', 'Full')] + $InstallProgressDisplayLevel, [Parameter()] [System.Boolean] - $ShouldUninstallOlderVersionsOfOffice = $true, + $ShouldUninstallOlderVersionsOfOffice, [Parameter()] [System.String] - $TargetVersion = "", -> + $TargetVersion, + [Parameter()] [System.String] - $UpdateVersion = "", + $UpdateVersion, [Parameter()] [System.Byte[]] @@ -767,7 +779,7 @@ function Test-TargetResource Add-M365DSCTelemetryEvent -Data $data #endregion - Write-Verbose -Message "Testing configuration of Intune Mobile MacOS App: {$DisplayName}" + Write-Verbose -Message "Testing configuration of Intune Mobile office suite App: {$DisplayName}" $CurrentValues = Get-TargetResource @PSBoundParameters if (-not (Test-M365DSCAuthenticationParameter -BoundParameters $CurrentValues)) From b6694e52013eb812a112b719aae201acf4876cf5 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Wed, 9 Oct 2024 22:05:45 -0700 Subject: [PATCH 03/32] finish get-target --- .../MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index 4cf91d3fc9..2d51a81d90 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -215,7 +215,6 @@ function Get-TargetResource PublishingState = $instance.PublishingState.ToString() RoleScopeTagIds = $instance.RoleScopeTagIds ProductIds = $instance.ProductIds - ExcludedApps = $instance.ExcludedApps UseSharedComputerActivation = $instance.UseSharedComputerActivation UpdateChannel = $instance.UpdateChannel OfficeSuiteAppDefaultFileFormat = $instance.OfficeSuiteAppDefaultFileFormat @@ -249,13 +248,13 @@ function Get-TargetResource $results.Add('Categories', "") } - #childApps - if($null -ne $instance.AdditionalProperties.childApps) + #ExcludedApps + if($null -ne $instance.AdditionalProperties.excludedApps) { - $results.Add('ChildApps', $instance.AdditionalProperties.childApps) + $results.Add('ExcludedApps', $instance.AdditionalProperties.excludedApps) } else { - $results.Add('ChildApps', "") + $results.Add('ExcludedApps', "") } #Assignments From 8d127f4e3a2d59ccba21942921c2c372c0a9c65b Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Wed, 9 Oct 2024 22:37:11 -0700 Subject: [PATCH 04/32] handle excludedapps --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 81 +++++++++---------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index 2d51a81d90..ce01f533da 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -65,7 +65,7 @@ function Get-TargetResource $ProductIds, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] + [PSCustomObject] $ExcludedApps, [Parameter()] @@ -249,12 +249,12 @@ function Get-TargetResource } #ExcludedApps - if($null -ne $instance.AdditionalProperties.excludedApps) + if ($null -ne $instance.AdditionalProperties -and $null -ne $instance.AdditionalProperties.excludedApps) { - $results.Add('ExcludedApps', $instance.AdditionalProperties.excludedApps) + $results['ExcludedApps'] = [PSCustomObject]$instance.AdditionalProperties.excludedApps } else { - $results.Add('ExcludedApps', "") + $results.Add('ExcludedApps', $null) } #Assignments @@ -363,7 +363,7 @@ function Set-TargetResource $ProductIds, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] + [PSCustomObject] $ExcludedApps, [Parameter()] @@ -504,8 +504,7 @@ function Set-TargetResource $CreateParameters.remove('Ensure') | Out-Null $CreateParameters.remove('Categories') | Out-Null $CreateParameters.remove('Assignments') | Out-Null - $CreateParameters.remove('childApps') | Out-Null - $CreateParameters.remove('IgnoreVersionDetection') | Out-Null + $CreateParameters.remove('excludedApps') | Out-Null $CreateParameters.Remove('Verbose') | Out-Null $CreateParameters.Remove('PublishingState') | Out-Null #Not allowed to update as it's a computed property $CreateParameters.Remove('LargeIcon') | Out-Null @@ -671,7 +670,7 @@ function Test-TargetResource $ProductIds, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] + [PSCustomObject] $ExcludedApps, [Parameter()] @@ -948,13 +947,13 @@ function Export-TargetResource $Results.Remove('Categories') | Out-Null } - #ChildApps - if($null -ne $Results.childApps) + #ExcludedApps + if($null -ne $Results.excludedApps) { - $Results.childApps = Get-M365DSCIntuneAppChildAppsAsString -ChildApps $Results.childApps + $Results.excludedApps = Get-M365DSCIntuneAppExcludedAppsAsString -ExcludedApps $Results.excludedApps } else { - $Results.Remove('childApps') | Out-Null + $Results.Remove('excludedApps') | Out-Null } #Assignments @@ -1004,16 +1003,16 @@ function Export-TargetResource $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Categories' -IsCIMArray:$isCIMArray } - #ChildApps - if ($null -ne $Results.childApps) + #ExcludedApps + if ($null -ne $Results.excludedApps) { $isCIMArray = $false - if ($Results.childApps.getType().Fullname -like '*[[\]]') + if ($Results.excludedApps.getType().Fullname -like '*[[\]]') { $isCIMArray = $true } - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ChildApps' -IsCIMArray:$isCIMArray + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ExcludedApps' -IsCIMArray:$isCIMArray } #Assignments @@ -1097,39 +1096,33 @@ function Get-M365DSCIntuneAppCategoriesAsString return $StringContent } -function Get-M365DSCIntuneAppChildAppsAsString +function Get-M365DSCIntuneAppExcludedAppsAsString { [CmdletBinding()] [OutputType([System.String])] param( [Parameter(Mandatory = $true)] - [System.Object[]] - $ChildApps + [System.Object] + $ExcludedApps ) - $StringContent = '@(' - $space = ' ' - $indent = ' ' - - $i = 1 - foreach ($childApp in $ChildApps) - { - if ($ChildApps.Count -gt 1) - { - $StringContent += "`r`n" - $StringContent += "$space" - } - - $StringContent += "MSFT_DeviceManagementMobileAppChildApp { `r`n" - $StringContent += "$($space)$($indent)bundleId = '" + $childApp.bundleId + "'`r`n" - $StringContent += "$($space)$($indent)buildNumber = '" + $childApp.buildNumber + "'`r`n" - $StringContent += "$($space)$($indent)versionNumber = '" + $childApp.versionNumber + "'`r`n" - $StringContent += "$space}" - - $i++ - } - - $StringContent += ')' + $StringContent = "@{" + $StringContent += "`n Access = '$($ExcludedApps.Access)'" + $StringContent += "`n Bing = '$($ExcludedApps.Bing)'" + $StringContent += "`n Excel = '$($ExcludedApps.Excel)'" + $StringContent += "`n Groove = '$($ExcludedApps.Groove)'" + $StringContent += "`n InfoPath = '$($ExcludedApps.InfoPath)'" + $StringContent += "`n Lync = '$($ExcludedApps.Lync)'" + $StringContent += "`n OneDrive = '$($ExcludedApps.OneDrive)'" + $StringContent += "`n OneNote = '$($ExcludedApps.OneNote)'" + $StringContent += "`n Outlook = '$($ExcludedApps.Outlook)'" + $StringContent += "`n PowerPoint = '$($ExcludedApps.PowerPoint)'" + $StringContent += "`n Publisher = '$($ExcludedApps.Publisher)'" + $StringContent += "`n SharePointDesigner = '$($ExcludedApps.SharePointDesigner)'" + $StringContent += "`n Teams = '$($ExcludedApps.Teams)'" + $StringContent += "`n Visio = '$($ExcludedApps.Visio)'" + $StringContent += "`n Word = '$($ExcludedApps.Word)'" + $StringContent += "`n}" return $StringContent } @@ -1146,8 +1139,8 @@ function Get-M365DSCIntuneMobileMocOSLobAppAdditionalProperties ) $additionalProperties = @( - 'IgnoreVersionDetection' - 'ChildApps' + 'AutoAcceptEula' + 'ExcludedApps' ) $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp' } From aa00aff1bb521f0496c1af92ce757fa9d2d44cfa Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Thu, 10 Oct 2024 14:07:54 -0700 Subject: [PATCH 05/32] add mof settings and readme files --- ...MobileAppsWindowsOfficeSuiteApp.schema.mof | 101 ++++++++++++++++-- .../readme.md | 4 +- .../settings.json | 28 ++--- 3 files changed, 111 insertions(+), 22 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof index fe8aabccae..a587398b50 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof @@ -1,14 +1,103 @@ -[ClassVersion("1.0.0.0"), FriendlyName("ResourceName")] -class MSFT_ResourceName : OMI_BaseResource +[ClassVersion("1.0.0"), FriendlyName("IntuneMobileAppsWindowsOfficeSuiteApp")] +class MSFT_IntuneMobileAppsWindowsOfficeSuiteApp : OMI_BaseResource { - [Key, Description("")] String PrimaryKey; - [Write, Description("")] String OtherProperties; + [Key, Description("The admin provided or imported title of the app. Inherited from mobileApp.")] String DisplayName; + [Write, Description("The unique identifier for an entity. Read-only. Inherited from mobileApp object.")] String Id; - [Write, Description("Present ensures the instance exists, absent ensures it is removed."), ValueMap{"Absent","Present"}, Values{"Absent","Present"}] string Ensure; - [Write, Description("Credentials of the workload's Admin"), EmbeddedInstance("MSFT_Credential")] string Credential; + [Write, Description("The description of the app. Inherited from mobileApp.")] String Description; + [Write, Description("The publisher of the app. Inherited from mobileApp.")] String Publisher; + [Write, Description("The value indicating whether the app is marked as featured by the admin. Inherited from mobileApp.")] Boolean IsFeatured; + [Write, Description("The privacy statement Url. Inherited from mobileApp.")] String PrivacyInformationUrl; + [Write, Description("The InformationUrl of the app. Inherited from mobileApp.")] String InformationUrl; + [Write, Description("The owner of the app. Inherited from mobileApp.")] String Owner; + [Write, Description("The dewveloper of the app. Inherited from mobileApp.")] String Developer; + [Write, Description("Notes for the app. Inherited from mobileApp.")] String Notes; + [Write, Description("The publishing state for the app. The app cannot be assigned unless the app is published. Inherited from mobileApp."), ValueMap{"notPublished", "processing","published"}, Values{"notPublished", "processing", "published"}] String PublishingState; + [Write, Description("List of Scope Tag IDs for mobile app.")] String RoleScopeTagIds[]; + [Write, Description("Specifies if the EULA is accepted automatically on the end user's device.")] Boolean AutoAcceptEula; + [Write, Description("The Product IDs that represent the Office 365 Suite SKU, such as 'O365ProPlusRetail' or 'VisioProRetail'.")] String ProductIds[]; + [Write, Description("Indicates whether shared computer activation is used for Office installations.")] Boolean UseSharedComputerActivation; + [Write, Description("Specifies the update channel for the Office 365 app suite, such as 'Current' or 'Deferred'.")] String UpdateChannel; + [Write, Description("Specifies the default file format type for Office apps, such as 'OfficeOpenXMLFormat' or 'OfficeOpenDocumentFormat'.")] String OfficeSuiteAppDefaultFileFormat; + [Write, Description("The architecture of the Office installation (e.g., 'X86', 'X64', or 'Arm64').")] String OfficePlatformArchitecture; + [Write, Description("Specifies the locales to be installed when the Office 365 apps are deployed. Uses the standard RFC 5646 format (e.g., 'en-US', 'fr-FR').")] String LocalesToInstall[]; + [Write, Description("Specifies the display level of the installation progress for Office apps. Use 'Full' to display the installation UI, or 'None' for a silent installation.")] String InstallProgressDisplayLevel; + [Write, Description("Indicates whether older versions of Office should be uninstalled when deploying the Office 365 app suite.")] Boolean ShouldUninstallOlderVersionsOfOffice; + [Write, Description("The specific target version of the Office 365 app suite to be deployed.")] String TargetVersion; + [Write, Description("The update version in which the target version is available for the Office 365 app suite.")] String UpdateVersion; + [Write, Description("A base64-encoded XML configuration file that specifies Office ProPlus installation settings. Takes precedence over all other properties. When present, this XML file will be used to create the app.")] String OfficeConfigurationXml; + [Write, Description("The list of categories for this app."), EmbeddedInstance("MSFT_DeviceManagementMobileAppCategory")] String Categories[]; + [Write, Description("The list of assignments for this app."), EmbeddedInstance("MSFT_DeviceManagementMobileAppAssignment")] String Assignments[]; + [Write, Description("The property that represents the apps excluded from the selected Office 365 Product ID."), EmbeddedInstance("MSFT_DeviceManagementMobileAppExcludedApp")] String ExcludedApps; + + [Write, Description("Present ensures the policy exists, absent ensures it is removed."), ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure; + [Write, Description("Credentials of the 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("Secret of the Azure Active Directory tenant used for authentication."), EmbeddedInstance("MSFT_Credential")] String ApplicationSecret; [Write, Description("Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication.")] String CertificateThumbprint; [Write, Description("Managed ID being used for authentication.")] Boolean ManagedIdentity; [Write, Description("Access token used for authentication.")] String AccessTokens[]; }; + +class MSFT_DeviceManagementMimeContent +{ + [Write, Description("Indicates the type of content mime.")] String type; + [Write, Description("The byte array that contains the actual content.")] String value[]; +}; + +class MSFT_DeviceManagementMobileAppCategory +{ + [Key, Description("The name of the app category.")] String displayName; + [Write, Description("The unique identifier for an entity. Read-only.")] String id; +}; + +class MSFT_DeviceManagementMobileAppChildApp +{ + [Write, Description("The bundleId of the app.")] String bundleId; + [Write, Description("The build number of the app.")] String buildNumber; + [Write, Description("The version number of the app.")] String versionNumber; +}; + +class MSFT_DeviceManagementMobileAppExcludedApp +{ + [Write, Description("Specifies whether to exclude Microsoft Office Access from the installation.")] Boolean Access; + [Write, Description("Specifies whether to exclude Microsoft Search (Bing) as the default from the installation.")] Boolean Bing; + [Write, Description("Specifies whether to exclude Microsoft Office Excel from the installation.")] Boolean Excel; + [Write, Description("Specifies whether to exclude Microsoft Office OneDrive for Business (Groove) from the installation.")] Boolean Groove; + [Write, Description("Specifies whether to exclude Microsoft Office InfoPath from the installation.")] Boolean InfoPath; + [Write, Description("Specifies whether to exclude Microsoft Office Skype for Business (Lync) from the installation.")] Boolean Lync; + [Write, Description("Specifies whether to exclude Microsoft Office OneDrive from the installation.")] Boolean OneDrive; + [Write, Description("Specifies whether to exclude Microsoft Office OneNote from the installation.")] Boolean OneNote; + [Write, Description("Specifies whether to exclude Microsoft Office Outlook from the installation.")] Boolean Outlook; + [Write, Description("Specifies whether to exclude Microsoft Office PowerPoint from the installation.")] Boolean PowerPoint; + [Write, Description("Specifies whether to exclude Microsoft Office Publisher from the installation.")] Boolean Publisher; + [Write, Description("Specifies whether to exclude Microsoft Office SharePoint Designer from the installation.")] Boolean SharePointDesigner; + [Write, Description("Specifies whether to exclude Microsoft Office Teams from the installation.")] Boolean Teams; + [Write, Description("Specifies whether to exclude Microsoft Office Visio from the installation.")] Boolean Visio; + [Write, Description("Specifies whether to exclude Microsoft Office Word from the installation.")] Boolean Word; +}; + +class MSFT_DeviceManagementMobileAppAssignment +{ + [Write, Description("The type of the target assignment."), + ValueMap{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget", "#microsoft.graph.mobileAppAssignment"}, + Values{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget", "#microsoft.graph.mobileAppAssignment"}] + String dataType; + + [Write, Description("The Id of the filter for the target assignment.")] String deviceAndAppManagementAssignmentFilterId; + [Write, Description("The type of filter of the target assignment i.e. Exclude or Include. Possible values are: none, include, exclude."), + ValueMap{"none", "include", "exclude"}, + Values{"none", "include", "exclude"}] + String deviceAndAppManagementAssignmentFilterType; + + [Write, Description("The group Id that is the target of the assignment.")] String groupId; + [Write, Description("The group Display Name that is the target of the assignment.")] String groupDisplayName; + + [Write, Description("Possible values for the install intent chosen by the admin."), + ValueMap{"available", "required", "uninstall", "availableWithoutEnrollment"}, + Values{"available", "required", "uninstall", "availableWithoutEnrollment"}] + String intent; + + [Write, Description("The source of this assignment.")] String source; +}; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/readme.md index 32e0e7fb27..f35ec06360 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/readme.md +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/readme.md @@ -1,6 +1,6 @@ -# ResourceName +# IntuneMobileAppsWindowsOfficeSuiteApp ## Description -##TODO - Provide a short description of what the resource is set to configure. +This resource configures an Intune mobile app of OfficeSuiteApp type for Windows devices. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/settings.json index edf14b05e4..a9bd04b5fa 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/settings.json +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/settings.json @@ -1,29 +1,29 @@ { - "resourceName": "ResourceName", - "description": "Description of what the resource is about.", - "roles": { - "read": [ - "Role" - ], - "update": [ - "Role" - ] - }, + "resourceName": "IntuneMobileAppsWindowsOfficeSuiteApp", + "description": "This resource configures an Intune mobile app.", "permissions": { "graph": { "delegated": { - "read": [], - "update": [] + "read": [ + { + "name": "DeviceManagementApps.Read.All" + } + ], + "update": [ + { + "name": "DeviceManagementApps.ReadWrite.All" + } + ] }, "application": { "read": [ { - "name": "Permission for Monitoring and Export" + "name": "DeviceManagementApps.Read.All" } ], "update": [ { - "name": "Permission for deploying" + "name": "DeviceManagementApps.ReadWrite.All" } ] } From 063adb301c5ad7fd37affe295d9fd61957edbde4 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Thu, 10 Oct 2024 16:12:40 -0700 Subject: [PATCH 06/32] add large icon in mof --- .../MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof index a587398b50..ef6cdaf8d0 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof @@ -14,6 +14,7 @@ class MSFT_IntuneMobileAppsWindowsOfficeSuiteApp : OMI_BaseResource [Write, Description("Notes for the app. Inherited from mobileApp.")] String Notes; [Write, Description("The publishing state for the app. The app cannot be assigned unless the app is published. Inherited from mobileApp."), ValueMap{"notPublished", "processing","published"}, Values{"notPublished", "processing", "published"}] String PublishingState; [Write, Description("List of Scope Tag IDs for mobile app.")] String RoleScopeTagIds[]; + [Write, Description("The icon for this app."), EmbeddedInstance("MSFT_DeviceManagementMimeContent")] String LargeIcon; [Write, Description("Specifies if the EULA is accepted automatically on the end user's device.")] Boolean AutoAcceptEula; [Write, Description("The Product IDs that represent the Office 365 Suite SKU, such as 'O365ProPlusRetail' or 'VisioProRetail'.")] String ProductIds[]; [Write, Description("Indicates whether shared computer activation is used for Office installations.")] Boolean UseSharedComputerActivation; From 6a3451a8a99b7a3639e2ada55bfdb1417dd10e37 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Thu, 10 Oct 2024 21:19:14 -0700 Subject: [PATCH 07/32] working export and compilation of generated file --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 92 ++++++++----------- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index ce01f533da..4cc90ae467 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -65,7 +65,7 @@ function Get-TargetResource $ProductIds, [Parameter()] - [PSCustomObject] + [System.Collections.Hashtable] $ExcludedApps, [Parameter()] @@ -248,10 +248,12 @@ function Get-TargetResource $results.Add('Categories', "") } - #ExcludedApps + # ExcludedApps if ($null -ne $instance.AdditionalProperties -and $null -ne $instance.AdditionalProperties.excludedApps) { - $results['ExcludedApps'] = [PSCustomObject]$instance.AdditionalProperties.excludedApps + $excludedAppsHashtable = @{} + $excludedAppsHashtable = [System.Collections.Hashtable]$instance.AdditionalProperties.excludedApps + $results['ExcludedApps'] = $excludedAppsHashtable } else { $results.Add('ExcludedApps', $null) @@ -363,7 +365,7 @@ function Set-TargetResource $ProductIds, [Parameter()] - [PSCustomObject] + [System.Collections.Hashtable] $ExcludedApps, [Parameter()] @@ -490,7 +492,7 @@ function Set-TargetResource $CreateParameters = ([Hashtable]$PSBoundParameters).clone() $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters - $AdditionalProperties = Get-M365DSCIntuneMobileMocOSLobAppAdditionalProperties -Properties ($CreateParameters) + $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($CreateParameters) foreach ($key in $AdditionalProperties.keys) { if ($key -ne '@odata.type') @@ -549,7 +551,7 @@ function Set-TargetResource $UpdateParameters = ([Hashtable]$PSBoundParameters).clone() $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters - $AdditionalProperties = Get-M365DSCIntuneMobileMocOSLobAppAdditionalProperties -Properties ($UpdateParameters) + $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($UpdateParameters) foreach ($key in $AdditionalProperties.keys) { if ($key -ne '@odata.type') @@ -670,7 +672,7 @@ function Test-TargetResource $ProductIds, [Parameter()] - [PSCustomObject] + [System.Collections.Hashtable] $ExcludedApps, [Parameter()] @@ -948,12 +950,12 @@ function Export-TargetResource } #ExcludedApps - if($null -ne $Results.excludedApps) + if ($null -ne $Results.ExcludedApps) { - $Results.excludedApps = Get-M365DSCIntuneAppExcludedAppsAsString -ExcludedApps $Results.excludedApps + $Results.ExcludedApps = Get-M365DSCIntuneAppExcludedAppsAsString -ExcludedApps $Results.ExcludedApps } else { - $Results.Remove('excludedApps') | Out-Null + $Results.Remove('ExcludedApps') | Out-Null } #Assignments @@ -1106,81 +1108,59 @@ function Get-M365DSCIntuneAppExcludedAppsAsString $ExcludedApps ) - $StringContent = "@{" - $StringContent += "`n Access = '$($ExcludedApps.Access)'" - $StringContent += "`n Bing = '$($ExcludedApps.Bing)'" - $StringContent += "`n Excel = '$($ExcludedApps.Excel)'" - $StringContent += "`n Groove = '$($ExcludedApps.Groove)'" - $StringContent += "`n InfoPath = '$($ExcludedApps.InfoPath)'" - $StringContent += "`n Lync = '$($ExcludedApps.Lync)'" - $StringContent += "`n OneDrive = '$($ExcludedApps.OneDrive)'" - $StringContent += "`n OneNote = '$($ExcludedApps.OneNote)'" - $StringContent += "`n Outlook = '$($ExcludedApps.Outlook)'" - $StringContent += "`n PowerPoint = '$($ExcludedApps.PowerPoint)'" - $StringContent += "`n Publisher = '$($ExcludedApps.Publisher)'" - $StringContent += "`n SharePointDesigner = '$($ExcludedApps.SharePointDesigner)'" - $StringContent += "`n Teams = '$($ExcludedApps.Teams)'" - $StringContent += "`n Visio = '$($ExcludedApps.Visio)'" - $StringContent += "`n Word = '$($ExcludedApps.Word)'" + # Create the embedded instance for ExcludedApps + $StringContent = "MSFT_DeviceManagementMobileAppExcludedApp {" + foreach ($key in $ExcludedApps.Keys) { + $value = if ($ExcludedApps[$key]) { '$true' } else { '$false' } + $StringContent += "`n $key = $value;" + } $StringContent += "`n}" return $StringContent } -function Get-M365DSCIntuneMobileMocOSLobAppAdditionalProperties +function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( - [Parameter(Mandatory = 'true')] + [Parameter(Mandatory = $true)] [System.Collections.Hashtable] $Properties ) - $additionalProperties = @( - 'AutoAcceptEula' - 'ExcludedApps' - ) + # Define the list of additional properties to include in the final payload + $additionalProperties = @('AutoAcceptEula', 'ExcludedApps') + + # Initialize a hashtable to store the additional properties + $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp'} - $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp' } + # Clone the original properties to manipulate $cloneProperties = $Properties.clone() + + # Loop through the clone and process each property based on its type foreach ($property in $cloneProperties.Keys) { if ($property -in $additionalProperties) { + # Convert property name to expected format $propertyName = $property[0].ToString().ToLower() + $property.Substring(1, $property.Length - 1) - if ($properties.$property -and $properties.$property.getType().FullName -like '*CIMInstance*') - { - if ($properties.$property.getType().FullName -like '*[[\]]') - { - $array = @() - foreach ($item in $properties.$property) - { - $array += Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $item - - } - $propertyValue = $array - } - else - { - $propertyValue = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $properties.$property - } + $propertyValue = $Properties.$property + # Handle ExcludedApps: Convert to PSCustomObject if it's a Hashtable + if ($propertyName -eq 'excludedApps' -and $propertyValue -is [System.Collections.Hashtable]) + { + $results.Add($propertyName, [PSCustomObject]$propertyValue) } else { - $propertyValue = $properties.$property + # For simple types like Boolean (AutoAcceptEula), add directly + $results.Add($propertyName, $propertyValue) } - - $results.Add($propertyName, $propertyValue) } } - if ($results.Count -eq 1) - { - return $null - } return $results } From eb39bee1de0bc8898115c26a679ccc50e772549b Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Fri, 11 Oct 2024 09:51:25 -0700 Subject: [PATCH 08/32] temp changes not working --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 163 ++++++++++++++---- 1 file changed, 127 insertions(+), 36 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index 4cc90ae467..7f6282e7b5 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -65,7 +65,7 @@ function Get-TargetResource $ProductIds, [Parameter()] - [System.Collections.Hashtable] + [Microsoft.Management.Infrastructure.CimInstance[]] $ExcludedApps, [Parameter()] @@ -248,14 +248,14 @@ function Get-TargetResource $results.Add('Categories', "") } - # ExcludedApps if ($null -ne $instance.AdditionalProperties -and $null -ne $instance.AdditionalProperties.excludedApps) { - $excludedAppsHashtable = @{} - $excludedAppsHashtable = [System.Collections.Hashtable]$instance.AdditionalProperties.excludedApps - $results['ExcludedApps'] = $excludedAppsHashtable - } - else { + $formattedExcludedApps = @{} + foreach ($key in $instance.AdditionalProperties.excludedApps.Keys) { + $formattedExcludedApps[$key] = if ($instance.AdditionalProperties.excludedApps[$key]) { $true } else { $false } + } + $results['ExcludedApps'] = $formattedExcludedApps + } else { $results.Add('ExcludedApps', $null) } @@ -274,12 +274,10 @@ function Get-TargetResource #LargeIcon # The large is returned only when Get cmdlet is called with Id parameter. The large icon is a base64 encoded string, so we need to convert it to a byte array. $instanceWithLargeIcon = Get-MgBetaDeviceAppManagementMobileApp -MobileAppId $instance.Id - if($null -ne $instanceWithLargeIcon.LargeIcon) - { + if (-not $results.ContainsKey('LargeIcon')) { $results.Add('LargeIcon', $instanceWithLargeIcon.LargeIcon) - } - else { - $results.Add('LargeIcon', "") + } else { + $results['LargeIcon'] = $instanceWithLargeIcon.LargeIcon # Update the existing key } #end region complex types @@ -365,7 +363,7 @@ function Set-TargetResource $ProductIds, [Parameter()] - [System.Collections.Hashtable] + [Microsoft.Management.Infrastructure.CimInstance[]] $ExcludedApps, [Parameter()] @@ -485,14 +483,26 @@ function Set-TargetResource $CreateParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters # CREATE + Write-Host "WE REACHED CREAAATE" + Write-Output "WE REACHED CREAAATE" if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') { + Write-Output "INSIDE IF STATEMENT" + Write-Host "INSIDE IF STATEMENT" Write-Host "Create office suite app: $DisplayName" $CreateParameters = ([Hashtable]$PSBoundParameters).clone() $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters - + Write-Host "Before AdditionalProperties creation: $($CreateParameters | Out-String)" + Write-Output "Before AdditionalProperties creation: $($CreateParameters | Out-String)" $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($CreateParameters) + Write-Host "AdditionalProperties: $($AdditionalProperties | Out-String)" + Write-Output "AdditionalProperties: $($AdditionalProperties | Out-String)" + # Explicitly enforce Hashtable type for AdditionalProperties + if ($null -ne $AdditionalProperties -and $AdditionalProperties -isnot [System.Collections.Hashtable]) + { + $AdditionalProperties = [System.Collections.Hashtable]$AdditionalProperties + } foreach ($key in $AdditionalProperties.keys) { if ($key -ne '@odata.type') @@ -528,15 +538,21 @@ function Set-TargetResource if($LargeIcon) { [System.Object]$LargeIconValue = ConvertTo-M365DSCIntuneAppLargeIcon -LargeIcon $LargeIcon - $CreateParameters.Add('LargeIcon', $LargeIconValue) + if (-not $CreateParameters.ContainsKey('LargeIcon')) { + $CreateParameters.Add('LargeIcon', $LargeIconValue) + } else { + $CreateParameters['LargeIcon'] = $LargeIconValue + } } - + Write-Output "CreateParameters before API call: $($CreateParameters | Out-String)" $app = New-MgBetaDeviceAppManagementMobileApp @CreateParameters #Assignments $assignmentsHash = ConvertTo-IntuneMobileAppAssignment -IncludeDeviceFilter:$true -Assignments $Assignments if ($app.id) { + Write-Host "Type of AdditionalProperties: $($AdditionalProperties.GetType().FullName)" + Write-Host "Contents of AdditionalProperties: $(ConvertTo-Json $AdditionalProperties)" Update-MgBetaDeviceAppManagementMobileAppAssignment -MobileAppId $app.id ` -Target $assignmentsHash ` -Repository 'deviceAppManagement/mobileAppAssignments' @@ -546,12 +562,16 @@ function Set-TargetResource elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') { Write-Host "Update office suite app: $DisplayName" - + Write-Output "INSIDE ELSE IF STATEMENT" + Write-Host "INSIDE ELSE IF STATEMENT" $PSBoundParameters.Remove('Assignments') | Out-Null $UpdateParameters = ([Hashtable]$PSBoundParameters).clone() $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters - + Write-Host "Before AdditionalProperties creation: $($CreateParameters | Out-String)" + Write-Output "Before AdditionalProperties creation: $($CreateParameters | Out-String)" $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($UpdateParameters) + Write-Host "AdditionalProperties after it's populated is: $($AdditionalProperties | Out-String)" + Write-Output "AdditionalProperties after it's populated is: $($AdditionalProperties | Out-String)" foreach ($key in $AdditionalProperties.keys) { if ($key -ne '@odata.type') @@ -584,8 +604,12 @@ function Set-TargetResource #LargeIcon if($LargeIcon) { - [System.Object]$LargeIconValue = ConvertTo-M365DSCIntuneAppLargeIcon -LargeIcon $LargeIcon - $UpdateParameters.Add('LargeIcon', $LargeIconValue) + [System.Object]$LargeIconValue = ConvertTo-M365DSCIntuneAppLargeIcon -LargeIcon $LargeIcon + if (-not $CreateParameters.ContainsKey('LargeIcon')) { + $UpdateParameters.Add('LargeIcon', $LargeIconValue) + } else { + $UpdateParameters['LargeIcon'] = $LargeIconValue + } } Update-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id @UpdateParameters @@ -601,6 +625,8 @@ function Set-TargetResource elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') { Write-Host "Remove office suite app: $DisplayName" + Write-Output "INSIDE SECOND ELSE IF STATEMENT" + Write-Host "INSIDE SECOND ELSE IF STATEMENT" Remove-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id -Confirm:$false } } @@ -672,7 +698,7 @@ function Test-TargetResource $ProductIds, [Parameter()] - [System.Collections.Hashtable] + [Microsoft.Management.Infrastructure.CimInstance[]] $ExcludedApps, [Parameter()] @@ -949,9 +975,13 @@ function Export-TargetResource $Results.Remove('Categories') | Out-Null } - #ExcludedApps + # ExcludedApps if ($null -ne $Results.ExcludedApps) { + # Convert to a Hashtable if still an array + if ($Results.ExcludedApps -is [System.Object[]]) { + $Results.ExcludedApps = Convert-ObjectArrayToHashtable -InputArray $Results.ExcludedApps + } $Results.ExcludedApps = Get-M365DSCIntuneAppExcludedAppsAsString -ExcludedApps $Results.ExcludedApps } else { @@ -1062,6 +1092,21 @@ function Export-TargetResource #region Helper functions +function Convert-ObjectArrayToHashtable { + param ( + [Parameter(Mandatory = $true)] + [System.Object[]] + $InputArray + ) + $outputHashTable = @{} + foreach ($element in $InputArray) { + if ($element -is [System.Collections.Hashtable]) { + $outputHashTable += $element + } + } + return $outputHashTable +} + function Get-M365DSCIntuneAppCategoriesAsString { [CmdletBinding()] @@ -1119,8 +1164,7 @@ function Get-M365DSCIntuneAppExcludedAppsAsString return $StringContent } -function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -{ +function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param @@ -1130,8 +1174,14 @@ function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties $Properties ) + Write-Host "WERE INSIDE THE HELPER FUNCTION" + Write-Output "WERE INSIDE THE HELPER FUNCTION" + # Define the list of additional properties to include in the final payload - $additionalProperties = @('AutoAcceptEula', 'ExcludedApps') + $additionalProperties = @( + 'AutoAcceptEula' + 'ExcludedApps' + ) # Initialize a hashtable to store the additional properties $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp'} @@ -1140,30 +1190,71 @@ function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties $cloneProperties = $Properties.clone() # Loop through the clone and process each property based on its type - foreach ($property in $cloneProperties.Keys) - { - if ($property -in $additionalProperties) - { + foreach ($property in $cloneProperties.Keys) { + if ($property -in $additionalProperties) { # Convert property name to expected format $propertyName = $property[0].ToString().ToLower() + $property.Substring(1, $property.Length - 1) $propertyValue = $Properties.$property - # Handle ExcludedApps: Convert to PSCustomObject if it's a Hashtable - if ($propertyName -eq 'excludedApps' -and $propertyValue -is [System.Collections.Hashtable]) - { - $results.Add($propertyName, [PSCustomObject]$propertyValue) + # Handle ExcludedApps: Build a single PSCustomObject with key-value pairs + if ($propertyName -eq 'excludedApps') { + $formattedExcludedApps = @{} + + # Convert each key in ExcludedApps to a key-value pair in a hashtable + foreach ($key in $propertyValue.Keys) { + # Ensure the value is correctly formatted as boolean $true or $false + $formattedExcludedApps[$key] = if ($propertyValue[$key]) { $true } else { $false } + } + + # Convert to PSCustomObject to match the expected format + $results.Add($propertyName, [PSCustomObject]$formattedExcludedApps) } - else - { + else { # For simple types like Boolean (AutoAcceptEula), add directly $results.Add($propertyName, $propertyValue) } } } - + Write-Host "Formatted ExcludedApps: $(ConvertTo-Json $results['excludedApps'])" + Write-Output "Formatted ExcludedApps: $(ConvertTo-Json $results['excludedApps'])" + Write-Host "Formatted AdditionalProperties: $(ConvertTo-Json $results)" + Write-Output "Formatted AdditionalProperties Type: $($results.GetType().FullName)" return $results } +# function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { +# [CmdletBinding()] +# [OutputType([System.Collections.Hashtable])] +# param +# ( +# [Parameter(Mandatory = $true)] +# [System.Collections.Hashtable] +# $Properties +# ) + +# # Initialize a hashtable to store only the relevant additional properties +# $results = @{} + +# # Add `excludedApps` if present +# if ($Properties.ContainsKey('ExcludedApps')) { +# $results.Add('excludedApps', $Properties['ExcludedApps']) +# } + +# # Add `autoAcceptEula` if present +# if ($Properties.ContainsKey('AutoAcceptEula')) { +# $results.Add('autoAcceptEula', $Properties['AutoAcceptEula']) +# } + +# # Debug output to ensure correct structure +# Write-Output "Formatted AdditionalProperties Type: $($results.GetType().FullName)" +# Write-Host "Formatted AdditionalProperties: $(ConvertTo-Json $results)" +# Write-Host "Formatted ExcludedApps: $(ConvertTo-Json $results['excludedApps'])" +# Write-Output "Formatted ExcludedApps: $(ConvertTo-Json $results['excludedApps'])" +# return $results +# } + + + function Get-M365DSCIntuneAppLargeIconAsString #Get and Export { [CmdletBinding()] From d106f44335c618817496fafdc9b913a4ba2e3fa7 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Sat, 12 Oct 2024 00:28:11 -0700 Subject: [PATCH 09/32] trying to fix excluded apps --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 144 ++++++++++-------- ...MobileAppsWindowsOfficeSuiteApp.schema.mof | 7 - 2 files changed, 78 insertions(+), 73 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index 7f6282e7b5..9b63396a4b 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -248,14 +248,29 @@ function Get-TargetResource $results.Add('Categories', "") } + # ExcludedApps if ($null -ne $instance.AdditionalProperties -and $null -ne $instance.AdditionalProperties.excludedApps) { - $formattedExcludedApps = @{} - foreach ($key in $instance.AdditionalProperties.excludedApps.Keys) { - $formattedExcludedApps[$key] = if ($instance.AdditionalProperties.excludedApps[$key]) { $true } else { $false } + # Convert to Hashtable if it is an array + if ($instance.AdditionalProperties.excludedApps -is [System.Object[]]) { + $formattedExcludedApps = @{} + foreach ($app in $instance.AdditionalProperties.excludedApps) { + foreach ($key in $app.Keys) { + $formattedExcludedApps[$key] = $app[$key] + } + } } - $results['ExcludedApps'] = $formattedExcludedApps - } else { + else { + $formattedExcludedApps = $instance.AdditionalProperties.excludedApps + } + + # Ensure ExcludedApps is returned as a Hashtable + $results['ExcludedApps'] = @{} + foreach ($key in $formattedExcludedApps.Keys) { + $results['ExcludedApps'].Add($key, $formattedExcludedApps[$key]) + } + } + else { $results.Add('ExcludedApps', $null) } @@ -483,26 +498,15 @@ function Set-TargetResource $CreateParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters # CREATE - Write-Host "WE REACHED CREAAATE" - Write-Output "WE REACHED CREAAATE" if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') { - Write-Output "INSIDE IF STATEMENT" - Write-Host "INSIDE IF STATEMENT" Write-Host "Create office suite app: $DisplayName" $CreateParameters = ([Hashtable]$PSBoundParameters).clone() $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters - Write-Host "Before AdditionalProperties creation: $($CreateParameters | Out-String)" Write-Output "Before AdditionalProperties creation: $($CreateParameters | Out-String)" $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($CreateParameters) - Write-Host "AdditionalProperties: $($AdditionalProperties | Out-String)" Write-Output "AdditionalProperties: $($AdditionalProperties | Out-String)" - # Explicitly enforce Hashtable type for AdditionalProperties - if ($null -ne $AdditionalProperties -and $AdditionalProperties -isnot [System.Collections.Hashtable]) - { - $AdditionalProperties = [System.Collections.Hashtable]$AdditionalProperties - } foreach ($key in $AdditionalProperties.keys) { if ($key -ne '@odata.type') @@ -551,8 +555,7 @@ function Set-TargetResource $assignmentsHash = ConvertTo-IntuneMobileAppAssignment -IncludeDeviceFilter:$true -Assignments $Assignments if ($app.id) { - Write-Host "Type of AdditionalProperties: $($AdditionalProperties.GetType().FullName)" - Write-Host "Contents of AdditionalProperties: $(ConvertTo-Json $AdditionalProperties)" + Write-Output "UpdateParameters before API call: $($UpdateParameters | Out-String)" Update-MgBetaDeviceAppManagementMobileAppAssignment -MobileAppId $app.id ` -Target $assignmentsHash ` -Repository 'deviceAppManagement/mobileAppAssignments' @@ -562,16 +565,12 @@ function Set-TargetResource elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') { Write-Host "Update office suite app: $DisplayName" - Write-Output "INSIDE ELSE IF STATEMENT" - Write-Host "INSIDE ELSE IF STATEMENT" + $PSBoundParameters.Remove('Assignments') | Out-Null $UpdateParameters = ([Hashtable]$PSBoundParameters).clone() $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters - Write-Host "Before AdditionalProperties creation: $($CreateParameters | Out-String)" - Write-Output "Before AdditionalProperties creation: $($CreateParameters | Out-String)" + $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($UpdateParameters) - Write-Host "AdditionalProperties after it's populated is: $($AdditionalProperties | Out-String)" - Write-Output "AdditionalProperties after it's populated is: $($AdditionalProperties | Out-String)" foreach ($key in $AdditionalProperties.keys) { if ($key -ne '@odata.type') @@ -625,8 +624,6 @@ function Set-TargetResource elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') { Write-Host "Remove office suite app: $DisplayName" - Write-Output "INSIDE SECOND ELSE IF STATEMENT" - Write-Host "INSIDE SECOND ELSE IF STATEMENT" Remove-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id -Confirm:$false } } @@ -1164,7 +1161,8 @@ function Get-M365DSCIntuneAppExcludedAppsAsString return $StringContent } -function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { +function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties +{ [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param @@ -1174,14 +1172,8 @@ function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { $Properties ) - Write-Host "WERE INSIDE THE HELPER FUNCTION" - Write-Output "WERE INSIDE THE HELPER FUNCTION" - # Define the list of additional properties to include in the final payload - $additionalProperties = @( - 'AutoAcceptEula' - 'ExcludedApps' - ) + $additionalProperties = @('AutoAcceptEula', 'ExcludedApps') # Initialize a hashtable to store the additional properties $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp'} @@ -1190,39 +1182,42 @@ function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { $cloneProperties = $Properties.clone() # Loop through the clone and process each property based on its type - foreach ($property in $cloneProperties.Keys) { - if ($property -in $additionalProperties) { + foreach ($property in $cloneProperties.Keys) + { + if ($property -in $additionalProperties) + { # Convert property name to expected format $propertyName = $property[0].ToString().ToLower() + $property.Substring(1, $property.Length - 1) $propertyValue = $Properties.$property - # Handle ExcludedApps: Build a single PSCustomObject with key-value pairs - if ($propertyName -eq 'excludedApps') { + # Handle ExcludedApps: Convert to a hashtable with camelCase properties + if ($propertyName -eq 'excludedApps' -and $propertyValue -is [System.Collections.Hashtable]) + { $formattedExcludedApps = @{} - # Convert each key in ExcludedApps to a key-value pair in a hashtable - foreach ($key in $propertyValue.Keys) { - # Ensure the value is correctly formatted as boolean $true or $false - $formattedExcludedApps[$key] = if ($propertyValue[$key]) { $true } else { $false } + # Convert each key in ExcludedApps to camelCase and add to formattedExcludedApps + foreach ($key in $propertyValue.Keys) + { + $camelCaseKey = $key.Substring(0, 1).ToLower() + $key.Substring(1) + $formattedExcludedApps[$camelCaseKey] = $propertyValue[$key] } # Convert to PSCustomObject to match the expected format $results.Add($propertyName, [PSCustomObject]$formattedExcludedApps) } - else { + else + { # For simple types like Boolean (AutoAcceptEula), add directly $results.Add($propertyName, $propertyValue) } } } - Write-Host "Formatted ExcludedApps: $(ConvertTo-Json $results['excludedApps'])" - Write-Output "Formatted ExcludedApps: $(ConvertTo-Json $results['excludedApps'])" - Write-Host "Formatted AdditionalProperties: $(ConvertTo-Json $results)" - Write-Output "Formatted AdditionalProperties Type: $($results.GetType().FullName)" + return $results } -# function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { +# function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties +# { # [CmdletBinding()] # [OutputType([System.Collections.Hashtable])] # param @@ -1232,29 +1227,46 @@ function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { # $Properties # ) -# # Initialize a hashtable to store only the relevant additional properties -# $results = @{} - -# # Add `excludedApps` if present -# if ($Properties.ContainsKey('ExcludedApps')) { -# $results.Add('excludedApps', $Properties['ExcludedApps']) +# # Define the list of additional properties to include in the final payload +# $additionalProperties = @('AutoAcceptEula', 'ExcludedApps') + +# # Initialize a hashtable to store the additional properties +# $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp'} + +# # Loop through the clone and process each property based on its type +# foreach ($property in $Properties.Keys) +# { +# if ($property -in $additionalProperties) +# { +# $propertyName = $property.Substring(0, 1).ToLower() + $property.Substring(1) +# $propertyValue = $Properties.$property + +# # Handle ExcludedApps as a hashtable with camelCase properties +# if ($propertyName -eq 'excludedApps' -and $propertyValue -is [System.Collections.Hashtable]) +# { +# $formattedExcludedApps = @{} + +# # Ensure the keys are camelCase +# foreach ($key in $propertyValue.Keys) +# { +# $camelCaseKey = $key.Substring(0, 1).ToLower() + $key.Substring(1) +# $formattedExcludedApps[$camelCaseKey] = $propertyValue[$key] +# } + +# # Convert it to PSCustomObject +# $results[$propertyName] = [PSCustomObject]$formattedExcludedApps +# } +# else +# { +# # For simple types, just add the value directly +# $results[$propertyName] = $propertyValue +# } +# } # } -# # Add `autoAcceptEula` if present -# if ($Properties.ContainsKey('AutoAcceptEula')) { -# $results.Add('autoAcceptEula', $Properties['AutoAcceptEula']) -# } - -# # Debug output to ensure correct structure -# Write-Output "Formatted AdditionalProperties Type: $($results.GetType().FullName)" -# Write-Host "Formatted AdditionalProperties: $(ConvertTo-Json $results)" -# Write-Host "Formatted ExcludedApps: $(ConvertTo-Json $results['excludedApps'])" -# Write-Output "Formatted ExcludedApps: $(ConvertTo-Json $results['excludedApps'])" # return $results # } - - function Get-M365DSCIntuneAppLargeIconAsString #Get and Export { [CmdletBinding()] diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof index ef6cdaf8d0..8613b2b42c 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof @@ -53,13 +53,6 @@ class MSFT_DeviceManagementMobileAppCategory [Write, Description("The unique identifier for an entity. Read-only.")] String id; }; -class MSFT_DeviceManagementMobileAppChildApp -{ - [Write, Description("The bundleId of the app.")] String bundleId; - [Write, Description("The build number of the app.")] String buildNumber; - [Write, Description("The version number of the app.")] String versionNumber; -}; - class MSFT_DeviceManagementMobileAppExcludedApp { [Write, Description("Specifies whether to exclude Microsoft Office Access from the installation.")] Boolean Access; From 61949a7977cb28c481e4a92382d0f8b88ded7471 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Sat, 12 Oct 2024 01:55:10 -0700 Subject: [PATCH 10/32] working version of excluded apps and additional properties --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 140 +++++++----------- ...MobileAppsWindowsOfficeSuiteApp.schema.mof | 96 +++++------- 2 files changed, 97 insertions(+), 139 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index 9b63396a4b..285d263f0c 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -505,8 +505,10 @@ function Set-TargetResource $CreateParameters = ([Hashtable]$PSBoundParameters).clone() $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters Write-Output "Before AdditionalProperties creation: $($CreateParameters | Out-String)" + Write-Host "Before AdditionalProperties creation: $($CreateParameters | Out-String)" $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($CreateParameters) Write-Output "AdditionalProperties: $($AdditionalProperties | Out-String)" + Write-Host "Before AdditionalProperties creation: $($CreateParameters | Out-String)" foreach ($key in $AdditionalProperties.keys) { if ($key -ne '@odata.type') @@ -569,8 +571,35 @@ function Set-TargetResource $PSBoundParameters.Remove('Assignments') | Out-Null $UpdateParameters = ([Hashtable]$PSBoundParameters).clone() $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters - $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($UpdateParameters) + # AdditionalProperties + Write-Host "AdditionalProperties content: $($AdditionalProperties | Out-String)" + + # If you want to specifically print the 'excludedApps' property within AdditionalProperties + if ($AdditionalProperties.ContainsKey('excludedApps')) { + Write-Host "ExcludedApps content: $($AdditionalProperties['excludedApps'] | Out-String)" + } else { + Write-Host "ExcludedApps not found in AdditionalProperties" + } + # Print the type of AdditionalProperties + if ($null -ne $AdditionalProperties) { + Write-Host "Type of AdditionalProperties: $($AdditionalProperties.GetType().FullName)" + } else { + Write-Host "AdditionalProperties is null." + } + # Check and print the type of ExcludedApps within AdditionalProperties + if ($AdditionalProperties.ContainsKey('excludedApps')) { + Write-Host "Type of excludedApps: $($AdditionalProperties['excludedApps'].GetType().FullName)" + } else { + Write-Host "excludedApps not found in AdditionalProperties." + } + $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties $CreateParameters + + # ExcludedApps should be properly formatted and passed to the API + if ($AdditionalProperties.ContainsKey('excludedApps')) { + Write-Host "Formatted ExcludedApps: $($AdditionalProperties['excludedApps'] | ConvertTo-Json -Depth 3)" + } + foreach ($key in $AdditionalProperties.keys) { if ($key -ne '@odata.type') @@ -582,9 +611,15 @@ function Set-TargetResource } $UpdateParameters.Remove('Id') | Out-Null - $UpdateParameters.Remove('Verbose') | Out-Null + # $UpdateParameters.Remove('Verbose') | Out-Null $UpdateParameters.Remove('Categories') | Out-Null $UpdateParameters.Remove('PublishingState') | Out-Null #Not allowed to update as it's a computed property + # Remove read-only properties before updating + $UpdateParameters.Remove('Developer') | Out-Null + $UpdateParameters.Remove('Owner') | Out-Null + $UpdateParameters.Remove('Publisher') | Out-Null + + Write-Host "UpdateParameters before API call: $($UpdateParameters | Out-String)" foreach ($key in ($UpdateParameters.clone()).Keys) { @@ -1161,15 +1196,12 @@ function Get-M365DSCIntuneAppExcludedAppsAsString return $StringContent } -function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -{ +function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] - param - ( + param ( [Parameter(Mandatory = $true)] - [System.Collections.Hashtable] - $Properties + [System.Collections.Hashtable] $Properties ) # Define the list of additional properties to include in the final payload @@ -1178,95 +1210,35 @@ function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties # Initialize a hashtable to store the additional properties $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp'} - # Clone the original properties to manipulate - $cloneProperties = $Properties.clone() - - # Loop through the clone and process each property based on its type - foreach ($property in $cloneProperties.Keys) - { - if ($property -in $additionalProperties) - { - # Convert property name to expected format - $propertyName = $property[0].ToString().ToLower() + $property.Substring(1, $property.Length - 1) + # Loop through and process each property based on its type + foreach ($property in $Properties.Keys) { + if ($property -in $additionalProperties) { + $propertyName = $property.Substring(0, 1).ToLower() + $property.Substring(1) $propertyValue = $Properties.$property - # Handle ExcludedApps: Convert to a hashtable with camelCase properties - if ($propertyName -eq 'excludedApps' -and $propertyValue -is [System.Collections.Hashtable]) - { + # Handle ExcludedApps as a hashtable with camelCase properties + if ($propertyName -eq 'excludedApps' -and $propertyValue -is [System.Array]) { $formattedExcludedApps = @{} - # Convert each key in ExcludedApps to camelCase and add to formattedExcludedApps - foreach ($key in $propertyValue.Keys) - { - $camelCaseKey = $key.Substring(0, 1).ToLower() + $key.Substring(1) - $formattedExcludedApps[$camelCaseKey] = $propertyValue[$key] + # Iterate over each CIMInstance object and extract the Name/Value pairs, converting to camelCase + foreach ($app in $propertyValue) { + foreach ($instanceProperty in $app.CimInstanceProperties) { + $camelCaseKey = $instanceProperty.Name.Substring(0, 1).ToLower() + $instanceProperty.Name.Substring(1) + $formattedExcludedApps[$camelCaseKey] = $instanceProperty.Value + } } - # Convert to PSCustomObject to match the expected format - $results.Add($propertyName, [PSCustomObject]$formattedExcludedApps) - } - else - { + # Add the formatted ExcludedApps to results + $results[$propertyName] = $formattedExcludedApps + } else { # For simple types like Boolean (AutoAcceptEula), add directly - $results.Add($propertyName, $propertyValue) + $results[$propertyName] = $propertyValue } } } - return $results } -# function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -# { -# [CmdletBinding()] -# [OutputType([System.Collections.Hashtable])] -# param -# ( -# [Parameter(Mandatory = $true)] -# [System.Collections.Hashtable] -# $Properties -# ) - -# # Define the list of additional properties to include in the final payload -# $additionalProperties = @('AutoAcceptEula', 'ExcludedApps') - -# # Initialize a hashtable to store the additional properties -# $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp'} - -# # Loop through the clone and process each property based on its type -# foreach ($property in $Properties.Keys) -# { -# if ($property -in $additionalProperties) -# { -# $propertyName = $property.Substring(0, 1).ToLower() + $property.Substring(1) -# $propertyValue = $Properties.$property - -# # Handle ExcludedApps as a hashtable with camelCase properties -# if ($propertyName -eq 'excludedApps' -and $propertyValue -is [System.Collections.Hashtable]) -# { -# $formattedExcludedApps = @{} - -# # Ensure the keys are camelCase -# foreach ($key in $propertyValue.Keys) -# { -# $camelCaseKey = $key.Substring(0, 1).ToLower() + $key.Substring(1) -# $formattedExcludedApps[$camelCaseKey] = $propertyValue[$key] -# } - -# # Convert it to PSCustomObject -# $results[$propertyName] = [PSCustomObject]$formattedExcludedApps -# } -# else -# { -# # For simple types, just add the value directly -# $results[$propertyName] = $propertyValue -# } -# } -# } - -# return $results -# } - function Get-M365DSCIntuneAppLargeIconAsString #Get and Export { [CmdletBinding()] diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof index 8613b2b42c..c91163da06 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof @@ -1,3 +1,44 @@ +class MSFT_DeviceManagementMobileAppAssignment +{ + [Write, Description("The type of the target assignment."), ValueMap{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget", "#microsoft.graph.mobileAppAssignment"}, Values{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget", "#microsoft.graph.mobileAppAssignment"}] String dataType; + [Write, Description("The Id of the filter for the target assignment.")] String deviceAndAppManagementAssignmentFilterId; + [Write, Description("The type of filter of the target assignment i.e. Exclude or Include. Possible values are: none, include, exclude."), ValueMap{"none", "include", "exclude"}, Values{"none", "include", "exclude"}] String deviceAndAppManagementAssignmentFilterType; + [Write, Description("The group Id that is the target of the assignment.")] String groupId; + [Write, Description("The group Display Name that is the target of the assignment.")] String groupDisplayName; + [Write, Description("Possible values for the install intent chosen by the admin."), ValueMap{"available", "required", "uninstall", "availableWithoutEnrollment"}, Values{"available", "required", "uninstall", "availableWithoutEnrollment"}] String intent; +}; + +class MSFT_DeviceManagementMimeContent +{ + [Write, Description("Indicates the type of content mime.")] String Type; + [Write, Description("The Base64 encoded string content.")] String Value; +}; + +class MSFT_DeviceManagementMobileAppCategory +{ + [Key, Description("The name of the app category.")] String DisplayName; + [Write, Description("The unique identifier for an entity. Read-only.")] String Id; +}; + +class MSFT_DeviceManagementMobileAppExcludedApp +{ + [Write, Description("Specifies whether to exclude Microsoft Office Access from the installation.")] Boolean Access; + [Write, Description("Specifies whether to exclude Microsoft Search (Bing) as the default from the installation.")] Boolean Bing; + [Write, Description("Specifies whether to exclude Microsoft Office Excel from the installation.")] Boolean Excel; + [Write, Description("Specifies whether to exclude Microsoft Office OneDrive for Business (Groove) from the installation.")] Boolean Groove; + [Write, Description("Specifies whether to exclude Microsoft Office InfoPath from the installation.")] Boolean InfoPath; + [Write, Description("Specifies whether to exclude Microsoft Office Skype for Business (Lync) from the installation.")] Boolean Lync; + [Write, Description("Specifies whether to exclude Microsoft Office OneDrive from the installation.")] Boolean OneDrive; + [Write, Description("Specifies whether to exclude Microsoft Office OneNote from the installation.")] Boolean OneNote; + [Write, Description("Specifies whether to exclude Microsoft Office Outlook from the installation.")] Boolean Outlook; + [Write, Description("Specifies whether to exclude Microsoft Office PowerPoint from the installation.")] Boolean PowerPoint; + [Write, Description("Specifies whether to exclude Microsoft Office Publisher from the installation.")] Boolean Publisher; + [Write, Description("Specifies whether to exclude Microsoft Office SharePoint Designer from the installation.")] Boolean SharePointDesigner; + [Write, Description("Specifies whether to exclude Microsoft Office Teams from the installation.")] Boolean Teams; + [Write, Description("Specifies whether to exclude Microsoft Office Visio from the installation.")] Boolean Visio; + [Write, Description("Specifies whether to exclude Microsoft Office Word from the installation.")] Boolean Word; +}; + [ClassVersion("1.0.0"), FriendlyName("IntuneMobileAppsWindowsOfficeSuiteApp")] class MSFT_IntuneMobileAppsWindowsOfficeSuiteApp : OMI_BaseResource { @@ -40,58 +81,3 @@ class MSFT_IntuneMobileAppsWindowsOfficeSuiteApp : OMI_BaseResource [Write, Description("Managed ID being used for authentication.")] Boolean ManagedIdentity; [Write, Description("Access token used for authentication.")] String AccessTokens[]; }; - -class MSFT_DeviceManagementMimeContent -{ - [Write, Description("Indicates the type of content mime.")] String type; - [Write, Description("The byte array that contains the actual content.")] String value[]; -}; - -class MSFT_DeviceManagementMobileAppCategory -{ - [Key, Description("The name of the app category.")] String displayName; - [Write, Description("The unique identifier for an entity. Read-only.")] String id; -}; - -class MSFT_DeviceManagementMobileAppExcludedApp -{ - [Write, Description("Specifies whether to exclude Microsoft Office Access from the installation.")] Boolean Access; - [Write, Description("Specifies whether to exclude Microsoft Search (Bing) as the default from the installation.")] Boolean Bing; - [Write, Description("Specifies whether to exclude Microsoft Office Excel from the installation.")] Boolean Excel; - [Write, Description("Specifies whether to exclude Microsoft Office OneDrive for Business (Groove) from the installation.")] Boolean Groove; - [Write, Description("Specifies whether to exclude Microsoft Office InfoPath from the installation.")] Boolean InfoPath; - [Write, Description("Specifies whether to exclude Microsoft Office Skype for Business (Lync) from the installation.")] Boolean Lync; - [Write, Description("Specifies whether to exclude Microsoft Office OneDrive from the installation.")] Boolean OneDrive; - [Write, Description("Specifies whether to exclude Microsoft Office OneNote from the installation.")] Boolean OneNote; - [Write, Description("Specifies whether to exclude Microsoft Office Outlook from the installation.")] Boolean Outlook; - [Write, Description("Specifies whether to exclude Microsoft Office PowerPoint from the installation.")] Boolean PowerPoint; - [Write, Description("Specifies whether to exclude Microsoft Office Publisher from the installation.")] Boolean Publisher; - [Write, Description("Specifies whether to exclude Microsoft Office SharePoint Designer from the installation.")] Boolean SharePointDesigner; - [Write, Description("Specifies whether to exclude Microsoft Office Teams from the installation.")] Boolean Teams; - [Write, Description("Specifies whether to exclude Microsoft Office Visio from the installation.")] Boolean Visio; - [Write, Description("Specifies whether to exclude Microsoft Office Word from the installation.")] Boolean Word; -}; - -class MSFT_DeviceManagementMobileAppAssignment -{ - [Write, Description("The type of the target assignment."), - ValueMap{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget", "#microsoft.graph.mobileAppAssignment"}, - Values{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget", "#microsoft.graph.mobileAppAssignment"}] - String dataType; - - [Write, Description("The Id of the filter for the target assignment.")] String deviceAndAppManagementAssignmentFilterId; - [Write, Description("The type of filter of the target assignment i.e. Exclude or Include. Possible values are: none, include, exclude."), - ValueMap{"none", "include", "exclude"}, - Values{"none", "include", "exclude"}] - String deviceAndAppManagementAssignmentFilterType; - - [Write, Description("The group Id that is the target of the assignment.")] String groupId; - [Write, Description("The group Display Name that is the target of the assignment.")] String groupDisplayName; - - [Write, Description("Possible values for the install intent chosen by the admin."), - ValueMap{"available", "required", "uninstall", "availableWithoutEnrollment"}, - Values{"available", "required", "uninstall", "availableWithoutEnrollment"}] - String intent; - - [Write, Description("The source of this assignment.")] String source; -}; From ae74a30f866e8ab47c6bec3bb69837f7a955509d Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Sun, 13 Oct 2024 11:43:56 -0700 Subject: [PATCH 11/32] current update with excluded apps not working --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 747 +++++++----------- 1 file changed, 276 insertions(+), 471 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index 285d263f0c..16a0858546 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -179,99 +179,108 @@ function Get-TargetResource $nullResult.Ensure = 'Absent' try { - $instance = Get-MgBetaDeviceAppManagementMobileApp ` - -Filter "(isof('microsoft.graph.officeSuiteApp') and displayName eq '$DisplayName')" ` - -ExpandProperty "categories,assignments" ` - -ErrorAction SilentlyContinue | Where-Object ` - -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.officeSuiteApp' } + $instance = Get-MgBetaDeviceAppManagementMobileApp -MobileAppId $Id ` + -ExpandProperty "categories" ` + -ErrorAction SilentlyContinue if ($null -eq $instance) { - Write-Verbose -Message "No Mobile app with DisplayName {$DisplayName} was found. Search with DisplayName." - $instance = Get-MgBetaDeviceAppManagementMobileApp ` - -MobileAppId $Id ` - -ExpandProperty "categories,assignments" ` - -ErrorAction Stop | Where-Object ` - -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.officeSuiteApp' } + Write-Verbose -Message "Could not find an Intune Windows Office Suite App with Id {$Id}." + + if (-not [System.String]::IsNullOrEmpty($DisplayName)) + { + $instance = Get-MgBetaDeviceAppManagementMobileApp ` + -Filter "(isof('microsoft.graph.officeSuiteApp') and displayName eq '$DisplayName')" ` + -ErrorAction SilentlyContinue + } + + if ($null -ne $instance) + { + $instance = Get-MgBetaDeviceAppManagementMobileApp -MobileAppId $instance.Id ` + -ExpandProperty "categories" ` + -ErrorAction SilentlyContinue + $Id = $instance.Id + } } if ($null -eq $instance) { - Write-Verbose -Message "No Mobile app with {$Id} was found." + Write-Verbose -Message "Could not find an Intune Windows Office Suite App with DisplayName {$DisplayName} was found." return $nullResult } - $results = @{ - Id = $instance.Id - DisplayName = $instance.DisplayName - Description = $instance.Description - Publisher = $instance.Publisher - IsFeatured = $instance.IsFeatured - PrivacyInformationUrl = $instance.PrivacyInformationUrl - InformationUrl = $instance.InformationUrl - Owner = $instance.Owner - Developer = $instance.Developer - Notes = $instance.Notes - PublishingState = $instance.PublishingState.ToString() - RoleScopeTagIds = $instance.RoleScopeTagIds - ProductIds = $instance.ProductIds - UseSharedComputerActivation = $instance.UseSharedComputerActivation - UpdateChannel = $instance.UpdateChannel - OfficeSuiteAppDefaultFileFormat = $instance.OfficeSuiteAppDefaultFileFormat - OfficePlatformArchitecture = $instance.OfficePlatformArchitecture - LocalesToInstall = $instance.LocalesToInstall - InstallProgressDisplayLevel = $instance.InstallProgressDisplayLevel - ShouldUninstallOlderVersionsOfOffice = $instance.ShouldUninstallOlderVersionsOfOffice - TargetVersion = $instance.TargetVersion - UpdateVersion = $instance.UpdateVersion - OfficeConfigurationXml = $instance.OfficeConfigurationXml - AutoAcceptEula = $instance.AdditionalProperties.AutoAcceptEula - - Ensure = 'Present' - Credential = $Credential - ApplicationId = $ApplicationId - TenantId = $TenantId - CertificateThumbprint = $CertificateThumbprint - ApplicationSecret = $ApplicationSecret - ManagedIdentity = $ManagedIdentity.IsPresent - AccessTokens = $AccessTokens - } + Write-Verbose "An Intune Windows Office Suite App with Id {$Id} and DisplayName {$DisplayName} was found." #region complex types - - #Categories - if($null -ne $instance.Categories) + $complexCategories = @() + foreach ($category in $instance.Categories) { - $results.Add('Categories', $instance.Categories) + $myCategory = @{} + $myCategory.Add('Id', $category.id) + $myCategory.Add('DisplayName', $category.displayName) + $complexCategories += $myCategory } - else { - $results.Add('Categories', "") + + $complexExcludedApps = [ordered]@{ + "access" = $instance.AdditionalProperties.excludedApps["access"] + "bing" = $instance.AdditionalProperties.excludedApps["bing"] + "excel" = $instance.AdditionalProperties.excludedApps["excel"] + "groove" = $instance.AdditionalProperties.excludedApps["groove"] + "infoPath" = $instance.AdditionalProperties.excludedApps["infoPath"] + "lync" = $instance.AdditionalProperties.excludedApps["lync"] + "oneDrive" = $instance.AdditionalProperties.excludedApps["oneDrive"] + "oneNote" = $instance.AdditionalProperties.excludedApps["oneNote"] + "outlook" = $instance.AdditionalProperties.excludedApps["outlook"] + "powerPoint" = $instance.AdditionalProperties.excludedApps["powerPoint"] + "publisher" = $instance.AdditionalProperties.excludedApps["publisher"] + "sharePointDesigner" = $instance.AdditionalProperties.excludedApps["sharePointDesigner"] + "teams" = $instance.AdditionalProperties.excludedApps["teams"] + "visio" = $instance.AdditionalProperties.excludedApps["visio"] + "word" = $instance.AdditionalProperties.excludedApps["word"] } - # ExcludedApps - if ($null -ne $instance.AdditionalProperties -and $null -ne $instance.AdditionalProperties.excludedApps) + $complexLargeIcon = @{} + if ($null -ne $instance.LargeIcon.Value) { - # Convert to Hashtable if it is an array - if ($instance.AdditionalProperties.excludedApps -is [System.Object[]]) { - $formattedExcludedApps = @{} - foreach ($app in $instance.AdditionalProperties.excludedApps) { - foreach ($key in $app.Keys) { - $formattedExcludedApps[$key] = $app[$key] - } - } - } - else { - $formattedExcludedApps = $instance.AdditionalProperties.excludedApps - } - - # Ensure ExcludedApps is returned as a Hashtable - $results['ExcludedApps'] = @{} - foreach ($key in $formattedExcludedApps.Keys) { - $results['ExcludedApps'].Add($key, $formattedExcludedApps[$key]) - } + $complexLargeIcon.Add('Value', [System.Convert]::ToBase64String($instance.LargeIcon.Value)) + $complexLargeIcon.Add('Type', $instance.LargeIcon.Type) } - else { - $results.Add('ExcludedApps', $null) + + $results = @{ + Id = $instance.Id + DisplayName = $instance.DisplayName + Description = $instance.Description + Publisher = $instance.Publisher + IsFeatured = $instance.IsFeatured + PrivacyInformationUrl = $instance.PrivacyInformationUrl + InformationUrl = $instance.InformationUrl + Owner = $instance.Owner + Developer = $instance.Developer + Notes = $instance.Notes + RoleScopeTagIds = $instance.RoleScopeTagIds + AutoAcceptEula = $instance.AdditionalProperties.autoAcceptEula + ProductIds = $instance.AdditionalProperties.productIds + UseSharedComputerActivation = $instance.AdditionalProperties.useSharedComputerActivation + UpdateChannel = $instance.AdditionalProperties.updateChannel + OfficeSuiteAppDefaultFileFormat = $instance.AdditionalProperties.officeSuiteAppDefaultFileFormat + OfficePlatformArchitecture = $instance.AdditionalProperties.officePlatformArchitecture + LocalesToInstall = $instance.AdditionalProperties.localesToInstall + InstallProgressDisplayLevel = $instance.AdditionalProperties.installProgressDisplayLevel + ShouldUninstallOlderVersionsOfOffice = $instance.AdditionalProperties.shouldUninstallOlderVersionsOfOffice + TargetVersion = $instance.AdditionalProperties.targetVersion + UpdateVersion = $instance.AdditionalProperties.updateVersion + OfficeConfigurationXml = $instance.AdditionalProperties.officeConfigurationXml + LargeIcon = $complexLargeIcon + ExcludedApps = $complexExcludedApps + Categories = $complexCategories + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ApplicationSecret = $ApplicationSecret + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens } #Assignments @@ -279,24 +288,20 @@ function Get-TargetResource $appAssignments = Get-MgBetaDeviceAppManagementMobileAppAssignment -MobileAppId $instance.Id if ($null -ne $appAssignments -and $appAssignments.count -gt 0) { - $resultAssignments += ConvertFrom-IntuneMobileAppAssignment ` - -IncludeDeviceFilter:$true ` - -Assignments ($appAssignments) - - $results.Add('Assignments', $resultAssignments) - } + $convertedAssignments = ConvertFrom-IntuneMobileAppAssignment ` + -IncludeDeviceFilter:$true ` + -Assignments ($appAssignments) + + # Filter out 'source' from the assignment objects + foreach ($assignment in $convertedAssignments) { + if ($assignment.ContainsKey('source')) { + $assignment.Remove('source') + } + } - #LargeIcon - # The large is returned only when Get cmdlet is called with Id parameter. The large icon is a base64 encoded string, so we need to convert it to a byte array. - $instanceWithLargeIcon = Get-MgBetaDeviceAppManagementMobileApp -MobileAppId $instance.Id - if (-not $results.ContainsKey('LargeIcon')) { - $results.Add('LargeIcon', $instanceWithLargeIcon.LargeIcon) - } else { - $results['LargeIcon'] = $instanceWithLargeIcon.LargeIcon # Update the existing key + $resultAssignments += $convertedAssignments } - - #end region complex types - + $results.Add('Assignments', $resultAssignments) return [System.Collections.Hashtable] $results } catch @@ -315,7 +320,7 @@ function Get-TargetResource function Set-TargetResource { [CmdletBinding()] - param + param ( #region Intune resource parameters @@ -486,179 +491,154 @@ function Set-TargetResource #endregion $currentInstance = Get-TargetResource @PSBoundParameters - $PSBoundParameters.Remove('Ensure') | Out-Null - $PSBoundParameters.Remove('Credential') | Out-Null - $PSBoundParameters.Remove('ApplicationId') | Out-Null - $PSBoundParameters.Remove('ApplicationSecret') | Out-Null - $PSBoundParameters.Remove('TenantId') | Out-Null - $PSBoundParameters.Remove('CertificateThumbprint') | Out-Null - $PSBoundParameters.Remove('ManagedIdentity') | Out-Null - $PSBoundParameters.Remove('AccessTokens') | Out-Null - - $CreateParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters - - # CREATE + $BoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') { - Write-Host "Create office suite app: $DisplayName" + Write-Verbose -Message "Creating an Intune Windows Office Suite App with DisplayName {$DisplayName}" + $BoundParameters.Remove('Assignments') | Out-Null - $CreateParameters = ([Hashtable]$PSBoundParameters).clone() + $CreateParameters = ([Hashtable]$BoundParameters).Clone() $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters - Write-Output "Before AdditionalProperties creation: $($CreateParameters | Out-String)" - Write-Host "Before AdditionalProperties creation: $($CreateParameters | Out-String)" - $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($CreateParameters) - Write-Output "AdditionalProperties: $($AdditionalProperties | Out-String)" - Write-Host "Before AdditionalProperties creation: $($CreateParameters | Out-String)" - foreach ($key in $AdditionalProperties.keys) + $CreateParameters.Remove('Id') | Out-Null + $CreateParameters.Remove('Categories') | Out-Null + + foreach ($key in ($CreateParameters.Clone()).Keys) { - if ($key -ne '@odata.type') + if ($null -ne $CreateParameters.$key -and $CreateParameters.$key.GetType().Name -like '*CimInstance*') { - $keyName = $key.substring(0, 1).ToUpper() + $key.substring(1, $key.length - 1) - $CreateParameters.remove($keyName) + $CreateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $CreateParameters.$key } } - $CreateParameters.remove('Id') | Out-Null - $CreateParameters.remove('Ensure') | Out-Null - $CreateParameters.remove('Categories') | Out-Null - $CreateParameters.remove('Assignments') | Out-Null - $CreateParameters.remove('excludedApps') | Out-Null - $CreateParameters.Remove('Verbose') | Out-Null - $CreateParameters.Remove('PublishingState') | Out-Null #Not allowed to update as it's a computed property - $CreateParameters.Remove('LargeIcon') | Out-Null + $CreateParameters.Add('@odata.type', '#microsoft.graph.officeSuiteApp') + $app = New-MgBetaDeviceAppManagementMobileApp -BodyParameter $CreateParameters - foreach ($key in ($CreateParameters.clone()).Keys) + foreach ($category in $Categories) { - if ($CreateParameters[$key].getType().Fullname -like '*CimInstance*') + if ($category.Id) { - $CreateParameters[$key] = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $CreateParameters[$key] + $currentCategory = Get-MgBetaDeviceAppManagementMobileAppCategory -CategoryId $category.Id + } + else + { + $currentCategory = Get-MgBetaDeviceAppManagementMobileAppCategory -Filter "displayName eq '$($category.DisplayName)'" } - } - if ($AdditionalProperties) - { - $CreateParameters.add('AdditionalProperties', $AdditionalProperties) - } + if ($null -eq $currentCategory) + { + throw "Mobile App Category with DisplayName $($category.DisplayName) not found." + } - #LargeIcon - if($LargeIcon) - { - [System.Object]$LargeIconValue = ConvertTo-M365DSCIntuneAppLargeIcon -LargeIcon $LargeIcon - if (-not $CreateParameters.ContainsKey('LargeIcon')) { - $CreateParameters.Add('LargeIcon', $LargeIconValue) - } else { - $CreateParameters['LargeIcon'] = $LargeIconValue + Invoke-MgBetaGraphRequest -Uri "/beta/deviceAppManagement/mobileApps/$($app.Id)/categories/`$ref" -Method 'POST' -Body @{ + '@odata.id' = "https://graph.microsoft.com/beta/deviceAppManagement/mobileAppCategories/$($currentCategory.Id)" } } - Write-Output "CreateParameters before API call: $($CreateParameters | Out-String)" - $app = New-MgBetaDeviceAppManagementMobileApp @CreateParameters #Assignments - $assignmentsHash = ConvertTo-IntuneMobileAppAssignment -IncludeDeviceFilter:$true -Assignments $Assignments - if ($app.id) + if ($app.Id) { - Write-Output "UpdateParameters before API call: $($UpdateParameters | Out-String)" - Update-MgBetaDeviceAppManagementMobileAppAssignment -MobileAppId $app.id ` - -Target $assignmentsHash ` - -Repository 'deviceAppManagement/mobileAppAssignments' + $assignmentsHash = ConvertTo-IntuneMobileAppAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + Update-DeviceAppManagementPolicyAssignment -AppManagementPolicyId $app.Id ` + -Assignments $assignmentsHash } } - # UPDATE elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') { - Write-Host "Update office suite app: $DisplayName" + Write-Host "Updating the Intune Windows Office Suite App with DisplayName {$DisplayName}" + $BoundParameters.Remove('Assignments') | Out-Null - $PSBoundParameters.Remove('Assignments') | Out-Null - $UpdateParameters = ([Hashtable]$PSBoundParameters).clone() + $UpdateParameters = ([Hashtable]$BoundParameters).Clone() $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters - $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties ($UpdateParameters) - # AdditionalProperties - Write-Host "AdditionalProperties content: $($AdditionalProperties | Out-String)" - - # If you want to specifically print the 'excludedApps' property within AdditionalProperties - if ($AdditionalProperties.ContainsKey('excludedApps')) { - Write-Host "ExcludedApps content: $($AdditionalProperties['excludedApps'] | Out-String)" - } else { - Write-Host "ExcludedApps not found in AdditionalProperties" - } - # Print the type of AdditionalProperties - if ($null -ne $AdditionalProperties) { - Write-Host "Type of AdditionalProperties: $($AdditionalProperties.GetType().FullName)" - } else { - Write-Host "AdditionalProperties is null." - } - # Check and print the type of ExcludedApps within AdditionalProperties - if ($AdditionalProperties.ContainsKey('excludedApps')) { - Write-Host "Type of excludedApps: $($AdditionalProperties['excludedApps'].GetType().FullName)" - } else { - Write-Host "excludedApps not found in AdditionalProperties." - } - $AdditionalProperties = Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties -Properties $CreateParameters - - # ExcludedApps should be properly formatted and passed to the API - if ($AdditionalProperties.ContainsKey('excludedApps')) { - Write-Host "Formatted ExcludedApps: $($AdditionalProperties['excludedApps'] | ConvertTo-Json -Depth 3)" - } - - foreach ($key in $AdditionalProperties.keys) - { - if ($key -ne '@odata.type') - { - $keyName = $key.substring(0, 1).ToUpper() + $key.substring(1, $key.length - 1) - #Remove additional keys, so that later they can be added as 'AdditionalProperties' - $UpdateParameters.Remove($keyName) - } - } - $UpdateParameters.Remove('Id') | Out-Null - # $UpdateParameters.Remove('Verbose') | Out-Null $UpdateParameters.Remove('Categories') | Out-Null - $UpdateParameters.Remove('PublishingState') | Out-Null #Not allowed to update as it's a computed property - # Remove read-only properties before updating + $UpdateParameters.Remove('OfficePlatformArchitecture') | Out-Null $UpdateParameters.Remove('Developer') | Out-Null $UpdateParameters.Remove('Owner') | Out-Null $UpdateParameters.Remove('Publisher') | Out-Null + $UpdateParameters.Remove('RoleScopeTagIds') | Out-Null + Write-Host "Initial ExcludedApps Data:" $ExcludedApps + + if ($UpdateParameters.ContainsKey('ExcludedApps')) { + # Convert ExcludedApps into an ordered hashtable using the same pattern as in the helper functions + $excludedAppsDict = [ordered]@{} + + # Define the list of known apps to exclude + $excludedAppsKeys = @( + 'access', 'bing', 'excel', 'groove', 'infoPath', 'lync', + 'oneDrive', 'oneNote', 'outlook', 'powerPoint', 'publisher', + 'sharePointDesigner', 'teams', 'visio', 'word' + ) + + # Loop through the known app keys and dynamically populate the dictionary + foreach ($key in $excludedAppsKeys) { + if ($AdditionalProperties['excludedApps'].ContainsKey($key)) { + $excludedAppsDict[$key] = $AdditionalProperties['excludedApps'][$key] + } else { + # Set default values for each key if not explicitly provided + if ($key -in @('groove', 'infoPath', 'lync', 'sharePointDesigner')) { + $excludedAppsDict[$key] = $true + } else { + $excludedAppsDict[$key] = $false + } + } + } - Write-Host "UpdateParameters before API call: $($UpdateParameters | Out-String)" + # Convert to JSON before sending to the API + $excludedAppsJson = $excludedAppsDict | ConvertTo-Json -Depth 3 - foreach ($key in ($UpdateParameters.clone()).Keys) - { - if ($UpdateParameters[$key].getType().Fullname -like '*CimInstance*') - { - $value = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $UpdateParameters[$key] - $UpdateParameters[$key] = $value - } + # Add this JSON to your parameters for the API + $UpdateParameters['excludedApps'] = $excludedAppsJson + } else { + Write-Host "ExcludedApps parameter not found in UpdateParameters." } - if ($AdditionalProperties) + # Print the entire UpdateParameters being sent to the API + Write-Host "Now ExcludedApps Data:" $UpdateParameters['excludedApps'] + + Update-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id -BodyParameter $UpdateParameters + + [array]$referenceObject = if ($null -ne $currentInstance.Categories.DisplayName) { $currentInstance.Categories.DisplayName } else { ,@() } + [array]$differenceObject = if ($null -ne $Categories.DisplayName) { $Categories.DisplayName } else { ,@() } + $delta = Compare-Object -ReferenceObject $referenceObject -DifferenceObject $differenceObject -PassThru + foreach ($diff in $delta) { - $UpdateParameters.Add('AdditionalProperties', $AdditionalProperties) - } + if ($diff.SideIndicator -eq '=>') + { + $category = $Categories | Where-Object { $_.DisplayName -eq $diff } + if ($category.Id) + { + $currentCategory = Get-MgBetaDeviceAppManagementMobileAppCategory -MobileAppCategoryId $category.Id + } + else + { + $currentCategory = Get-MgBetaDeviceAppManagementMobileAppCategory -Filter "displayName eq '$($category.DisplayName)'" + } - #LargeIcon - if($LargeIcon) - { - [System.Object]$LargeIconValue = ConvertTo-M365DSCIntuneAppLargeIcon -LargeIcon $LargeIcon - if (-not $CreateParameters.ContainsKey('LargeIcon')) { - $UpdateParameters.Add('LargeIcon', $LargeIconValue) - } else { - $UpdateParameters['LargeIcon'] = $LargeIconValue - } - } + if ($null -eq $currentCategory) + { + throw "Mobile App Category with DisplayName $($category.DisplayName) not found." + } - Update-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id @UpdateParameters - Write-Host "Updated office suite App: $DisplayName." + Invoke-MgGraphRequest -Uri "/beta/deviceAppManagement/mobileApps/$($currentInstance.Id)/categories/`$ref" -Method 'POST' -Body @{ + '@odata.id' = "https://graph.microsoft.com/beta/deviceAppManagement/mobileAppCategories/$($currentCategory.Id)" + } + } + else + { + $category = $currentInstance.Categories | Where-Object { $_.DisplayName -eq $diff } + Invoke-MgGraphRequest -Uri "/beta/deviceAppManagement/mobileApps/$($currentInstance.Id)/categories/$($category.Id)/`$ref" -Method 'DELETE' + } + } #Assignments $assignmentsHash = ConvertTo-IntuneMobileAppAssignment -IncludeDeviceFilter:$true -Assignments $Assignments - Update-MgBetaDeviceAppManagementMobileAppAssignment -MobileAppId $currentInstance.id ` - -Target $assignmentsHash ` - -Repository 'deviceAppManagement/mobileAppAssignments' + Update-DeviceAppManagementPolicyAssignment -AppManagementPolicyId $currentInstance.Id ` + -Assignments $assignmentsHash } - # REMOVE elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') { - Write-Host "Remove office suite app: $DisplayName" + Write-Host "Remove the Intune MacOS Lob App with Id {$($currentInstance.Id)}" Remove-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id -Confirm:$false } } @@ -667,7 +647,7 @@ function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] - param + param ( #region Intune resource parameters @@ -837,20 +817,10 @@ function Test-TargetResource Add-M365DSCTelemetryEvent -Data $data #endregion - Write-Verbose -Message "Testing configuration of Intune Mobile office suite App: {$DisplayName}" + Write-Verbose -Message "Testing configuration of the Intune Windows Suite App with Id {$Id} and DisplayName {$DisplayName}" $CurrentValues = Get-TargetResource @PSBoundParameters - if (-not (Test-M365DSCAuthenticationParameter -BoundParameters $CurrentValues)) - { - Write-Verbose "An error occured in Get-TargetResource, the app {$displayName} will not be processed" - throw "An error occured in Get-TargetResource, the app {$displayName} will not be processed. Refer to the event viewer logs for more information." - } - $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck - $ValuesToCheck.Remove('Id') | Out-Null - - Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" - Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() if ($CurrentValues.Ensure -ne $Ensure) { @@ -864,15 +834,14 @@ function Test-TargetResource { $source = $PSBoundParameters.$key $target = $CurrentValues.$key - if ($source.getType().Name -like '*CimInstance*') + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') { $testResult = Compare-M365DSCComplexObject ` -Source ($source) ` -Target ($target) - if (-Not $testResult) + if (-not $testResult) { - $testResult = $false break } @@ -880,6 +849,17 @@ function Test-TargetResource } } + # Prevent screen from filling up with the LargeIcon value + # Comparison will already be done because it's a CimInstance + $CurrentValues.Remove('LargeIcon') | Out-Null + $PSBoundParameters.Remove('LargeIcon') | Out-Null + + $ValuesToCheck.Remove('Id') | Out-Null + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + if ($testResult) { $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` @@ -899,6 +879,10 @@ function Export-TargetResource [OutputType([System.String])] param ( + [Parameter()] + [System.String] + $Filter, + [Parameter()] [System.Management.Automation.PSCredential] $Credential, @@ -948,9 +932,7 @@ function Export-TargetResource $Script:ExportMode = $true [array] $Script:getInstances = Get-MgBetaDeviceAppManagementMobileApp ` -Filter "isof('microsoft.graph.officeSuiteApp')" ` - -ExpandProperty "categories,assignments" ` - -ErrorAction Stop | Where-Object ` - -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.officeSuiteApp' } + -ErrorAction Stop $i = 1 $dscContent = '' @@ -990,61 +972,73 @@ function Export-TargetResource $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` -Results $Results - if (-not (Test-M365DSCAuthenticationParameter -BoundParameters $Results)) - { - Write-Verbose "An error occured in Get-TargetResource, the app {$($params.displayName)} will not be processed." - throw "An error occured in Get-TargetResource, the app {$($params.displayName)} will not be processed. Refer to the event viewer logs for more information." - } - #region complex types - - #Categories - if($null -ne $Results.Categories) + if ($null -ne $Results.Categories) { - $Results.Categories = Get-M365DSCIntuneAppCategoriesAsString -Categories $Results.Categories - } - else { - $Results.Remove('Categories') | Out-Null + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.Categories ` + -CIMInstanceName 'DeviceManagementMobileAppCategory' + + if (-not [System.String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.Categories = $complexTypeStringResult + } + else + { + $Results.Remove('Categories') | Out-Null + } } - # ExcludedApps if ($null -ne $Results.ExcludedApps) { - # Convert to a Hashtable if still an array - if ($Results.ExcludedApps -is [System.Object[]]) { - $Results.ExcludedApps = Convert-ObjectArrayToHashtable -InputArray $Results.ExcludedApps + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.ExcludedApps ` + -CIMInstanceName 'DeviceManagementMobileAppExcludedApp' + + if (-not [System.String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.ExcludedApps = $complexTypeStringResult + } + else + { + $Results.Remove('ExcludedApps') | Out-Null } - $Results.ExcludedApps = Get-M365DSCIntuneAppExcludedAppsAsString -ExcludedApps $Results.ExcludedApps - } - else { - $Results.Remove('ExcludedApps') | Out-Null } - #Assignments - if ($null -ne $Results.Assignments) + if ($null -ne $Results.LargeIcon) { - $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject ([Array]$Results.Assignments) -CIMInstanceName DeviceManagementMobileAppAssignment + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.LargeIcon ` + -CIMInstanceName 'DeviceManagementMimeContent' - if ($complexTypeStringResult) + if (-not [System.String]::IsNullOrWhiteSpace($complexTypeStringResult)) { - $Results.Assignments = $complexTypeStringResult + $Results.LargeIcon = $complexTypeStringResult } else { - $Results.Remove('Assignments') | Out-Null + $Results.Remove('LargeIcon') | Out-Null } } - #LargeIcon - if($null -ne $Results.LargeIcon) - { - $Results.LargeIcon = Get-M365DSCIntuneAppLargeIconAsString -LargeIcon $Results.LargeIcon - } - else + if ($null -ne $Results.Assignments) { - $Results.Remove('LargeIcon') | Out-Null - } + if ($Results.Assignments) + { + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.Assignments ` + -CIMInstanceName DeviceManagementMobileAppAssignment + if ($complexTypeStringResult) + { + $Results.Assignments = $complexTypeStringResult + } + else + { + $Results.Remove('Assignments') | Out-Null + } + } + } #endregion complex types $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` @@ -1054,49 +1048,25 @@ function Export-TargetResource -Credential $Credential #region complex types - - #Categories if ($null -ne $Results.Categories) { - $isCIMArray = $false - if ($Results.Categories.getType().Fullname -like '*[[\]]') - { - $isCIMArray = $true - } - - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Categories' -IsCIMArray:$isCIMArray - } - - #ExcludedApps - if ($null -ne $Results.excludedApps) - { - $isCIMArray = $false - if ($Results.excludedApps.getType().Fullname -like '*[[\]]') - { - $isCIMArray = $true - } - - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ExcludedApps' -IsCIMArray:$isCIMArray + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Categories' -IsCIMArray:$true } - #Assignments - if ($null -ne $Results.Assignments) + if ($null -ne $Results.ExcludedApps) { - $isCIMArray = $false - if ($Results.Assignments.getType().Fullname -like '*[[\]]') - { - $isCIMArray = $true - } - - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Assignments' -IsCIMArray:$isCIMArray + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ExcludedApps' -IsCIMArray:$true } - #LargeIcon if ($null -ne $Results.LargeIcon) { $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'LargeIcon' -IsCIMArray:$false } + if ($null -ne $Results.Assignments) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Assignments' -IsCIMArray:$true + } #endregion complex types $dscContent += $currentDSCBlock @@ -1122,169 +1092,4 @@ function Export-TargetResource } } -#region Helper functions - -function Convert-ObjectArrayToHashtable { - param ( - [Parameter(Mandatory = $true)] - [System.Object[]] - $InputArray - ) - $outputHashTable = @{} - foreach ($element in $InputArray) { - if ($element -is [System.Collections.Hashtable]) { - $outputHashTable += $element - } - } - return $outputHashTable -} - -function Get-M365DSCIntuneAppCategoriesAsString -{ - [CmdletBinding()] - [OutputType([System.String])] - param( - [Parameter(Mandatory = $true)] - [System.Object[]] - $Categories - ) - - $StringContent = '@(' - $space = ' ' - $indent = ' ' - - $i = 1 - foreach ($category in $Categories) - { - if ($Categories.Count -gt 1) - { - $StringContent += "`r`n" - $StringContent += "$space" - } - - #Only export the displayName, not Id - $StringContent += "MSFT_DeviceManagementMobileAppCategory { `r`n" - $StringContent += "$($space)$($indent)displayName = '" + $category.displayName + "'`r`n" - $StringContent += "$space}" - - $i++ - } - - $StringContent += ')' - - return $StringContent -} - -function Get-M365DSCIntuneAppExcludedAppsAsString -{ - [CmdletBinding()] - [OutputType([System.String])] - param( - [Parameter(Mandatory = $true)] - [System.Object] - $ExcludedApps - ) - - # Create the embedded instance for ExcludedApps - $StringContent = "MSFT_DeviceManagementMobileAppExcludedApp {" - foreach ($key in $ExcludedApps.Keys) { - $value = if ($ExcludedApps[$key]) { '$true' } else { '$false' } - $StringContent += "`n $key = $value;" - } - $StringContent += "`n}" - - return $StringContent -} - -function Get-M365DSCIntuneMobileWindowsOfficeSuiteAppAdditionalProperties { - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param ( - [Parameter(Mandatory = $true)] - [System.Collections.Hashtable] $Properties - ) - - # Define the list of additional properties to include in the final payload - $additionalProperties = @('AutoAcceptEula', 'ExcludedApps') - - # Initialize a hashtable to store the additional properties - $results = @{'@odata.type' = '#microsoft.graph.officeSuiteApp'} - - # Loop through and process each property based on its type - foreach ($property in $Properties.Keys) { - if ($property -in $additionalProperties) { - $propertyName = $property.Substring(0, 1).ToLower() + $property.Substring(1) - $propertyValue = $Properties.$property - - # Handle ExcludedApps as a hashtable with camelCase properties - if ($propertyName -eq 'excludedApps' -and $propertyValue -is [System.Array]) { - $formattedExcludedApps = @{} - - # Iterate over each CIMInstance object and extract the Name/Value pairs, converting to camelCase - foreach ($app in $propertyValue) { - foreach ($instanceProperty in $app.CimInstanceProperties) { - $camelCaseKey = $instanceProperty.Name.Substring(0, 1).ToLower() + $instanceProperty.Name.Substring(1) - $formattedExcludedApps[$camelCaseKey] = $instanceProperty.Value - } - } - - # Add the formatted ExcludedApps to results - $results[$propertyName] = $formattedExcludedApps - } else { - # For simple types like Boolean (AutoAcceptEula), add directly - $results[$propertyName] = $propertyValue - } - } - } - return $results -} - -function Get-M365DSCIntuneAppLargeIconAsString #Get and Export -{ - [CmdletBinding()] - [OutputType([System.String])] - param( - [Parameter(Mandatory = $true)] - [System.Object] - $LargeIcon - ) - - $space = ' ' - $indent = ' ' - - if ($null -ne $LargeIcon.Value) - { - $StringContent += "`r`n" - $StringContent += "$space" - - $base64String = [System.Convert]::ToBase64String($LargeIcon.Value) # This exports the base64 string (blob) of the byte array, same as we see in Graph API response - - $StringContent += "MSFT_DeviceManagementMimeContent { `r`n" - $StringContent += "$($space)$($indent)type = '" + $LargeIcon.Type + "'`r`n" - $StringContent += "$($space)$($indent)value = '" + $base64String + "'`r`n" - $StringContent += "$space}" - } - - return $StringContent - } - -function ConvertTo-M365DSCIntuneAppLargeIcon #set -{ - [OutputType([System.Object])] - param( - [Parameter(Mandatory = $true)] - [System.Object] - $LargeIcon - ) - - $result = @{ - type = $LargeIcon.Type - value = $iconValue - } - - return $result -} - -#endregion Helper functions - Export-ModuleMember -Function *-TargetResource From 3dcd4d0d99d9426b5023ef195fc9fc59eabc7e98 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Sun, 13 Oct 2024 12:25:43 -0700 Subject: [PATCH 12/32] change to cim instance not cim instance [] --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 69 +++++++------------ 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index 16a0858546..b5d33dcc05 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -65,7 +65,7 @@ function Get-TargetResource $ProductIds, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] + [Microsoft.Management.Infrastructure.CimInstance] $ExcludedApps, [Parameter()] @@ -221,22 +221,12 @@ function Get-TargetResource $complexCategories += $myCategory } - $complexExcludedApps = [ordered]@{ - "access" = $instance.AdditionalProperties.excludedApps["access"] - "bing" = $instance.AdditionalProperties.excludedApps["bing"] - "excel" = $instance.AdditionalProperties.excludedApps["excel"] - "groove" = $instance.AdditionalProperties.excludedApps["groove"] - "infoPath" = $instance.AdditionalProperties.excludedApps["infoPath"] - "lync" = $instance.AdditionalProperties.excludedApps["lync"] - "oneDrive" = $instance.AdditionalProperties.excludedApps["oneDrive"] - "oneNote" = $instance.AdditionalProperties.excludedApps["oneNote"] - "outlook" = $instance.AdditionalProperties.excludedApps["outlook"] - "powerPoint" = $instance.AdditionalProperties.excludedApps["powerPoint"] - "publisher" = $instance.AdditionalProperties.excludedApps["publisher"] - "sharePointDesigner" = $instance.AdditionalProperties.excludedApps["sharePointDesigner"] - "teams" = $instance.AdditionalProperties.excludedApps["teams"] - "visio" = $instance.AdditionalProperties.excludedApps["visio"] - "word" = $instance.AdditionalProperties.excludedApps["word"] + $complexExcludedApps = [ordered]@{} + if ($null -ne $instance.AdditionalProperties.excludedApps) { + foreach ($property in $instance.AdditionalProperties.excludedApps.CimInstanceProperties) { + $camelCaseName = $property.Name.Substring(0, 1).ToLower() + $property.Name.Substring(1) + $complexExcludedApps[$camelCaseName] = $property.Value + } } $complexLargeIcon = @{} @@ -383,7 +373,7 @@ function Set-TargetResource $ProductIds, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] + [Microsoft.Management.Infrastructure.CimInstance] $ExcludedApps, [Parameter()] @@ -560,35 +550,24 @@ function Set-TargetResource Write-Host "Initial ExcludedApps Data:" $ExcludedApps if ($UpdateParameters.ContainsKey('ExcludedApps')) { - # Convert ExcludedApps into an ordered hashtable using the same pattern as in the helper functions - $excludedAppsDict = [ordered]@{} - - # Define the list of known apps to exclude - $excludedAppsKeys = @( - 'access', 'bing', 'excel', 'groove', 'infoPath', 'lync', - 'oneDrive', 'oneNote', 'outlook', 'powerPoint', 'publisher', - 'sharePointDesigner', 'teams', 'visio', 'word' - ) - - # Loop through the known app keys and dynamically populate the dictionary - foreach ($key in $excludedAppsKeys) { - if ($AdditionalProperties['excludedApps'].ContainsKey($key)) { - $excludedAppsDict[$key] = $AdditionalProperties['excludedApps'][$key] - } else { - # Set default values for each key if not explicitly provided - if ($key -in @('groove', 'infoPath', 'lync', 'sharePointDesigner')) { - $excludedAppsDict[$key] = $true - } else { - $excludedAppsDict[$key] = $false - } + if ($ExcludedApps -ne $null) { + $excludedAppsDict = [ordered]@{} + + foreach ($property in $ExcludedApps.CimInstanceProperties) { + $camelCaseName = $property.Name.Substring(0, 1).ToLower() + $property.Name.Substring(1) + $excludedAppsDict[$camelCaseName] = $property.Value } - } - # Convert to JSON before sending to the API - $excludedAppsJson = $excludedAppsDict | ConvertTo-Json -Depth 3 + # Convert the hashtable to a dictionary for API submission + $excludedAppsDictTyped = [System.Collections.Generic.Dictionary[string, bool]]::new() + foreach ($key in $excludedAppsDict.Keys) { + $excludedAppsDictTyped.Add($key, $excludedAppsDict[$key]) + } - # Add this JSON to your parameters for the API - $UpdateParameters['excludedApps'] = $excludedAppsJson + $UpdateParameters['excludedApps'] = $excludedAppsDictTyped + } else { + Write-Host "ExcludedApps is null." + } } else { Write-Host "ExcludedApps parameter not found in UpdateParameters." } @@ -710,7 +689,7 @@ function Test-TargetResource $ProductIds, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] + [Microsoft.Management.Infrastructure.CimInstance] $ExcludedApps, [Parameter()] From 5d170dab17c0af29182eb1e104dc5705a7e79a84 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Sun, 13 Oct 2024 12:43:29 -0700 Subject: [PATCH 13/32] not working excluded apps without dictionary conversion --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 57 +++++++++++-------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index b5d33dcc05..8b9a78e64e 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -221,13 +221,13 @@ function Get-TargetResource $complexCategories += $myCategory } - $complexExcludedApps = [ordered]@{} - if ($null -ne $instance.AdditionalProperties.excludedApps) { - foreach ($property in $instance.AdditionalProperties.excludedApps.CimInstanceProperties) { - $camelCaseName = $property.Name.Substring(0, 1).ToLower() + $property.Name.Substring(1) - $complexExcludedApps[$camelCaseName] = $property.Value - } - } + # $complexExcludedApps = [ordered]@{} + # if ($null -ne $instance.AdditionalProperties.excludedApps) { + # foreach ($property in $instance.AdditionalProperties.excludedApps.CimInstanceProperties) { + # $camelCaseName = $property.Name.Substring(0, 1).ToLower() + $property.Name.Substring(1) + # $complexExcludedApps[$camelCaseName] = $property.Value + # } + # } $complexLargeIcon = @{} if ($null -ne $instance.LargeIcon.Value) @@ -261,7 +261,7 @@ function Get-TargetResource UpdateVersion = $instance.AdditionalProperties.updateVersion OfficeConfigurationXml = $instance.AdditionalProperties.officeConfigurationXml LargeIcon = $complexLargeIcon - ExcludedApps = $complexExcludedApps + ExcludedApps = $instance.AdditionalProperties.excludedApps Categories = $complexCategories Ensure = 'Present' Credential = $Credential @@ -549,27 +549,36 @@ function Set-TargetResource $UpdateParameters.Remove('RoleScopeTagIds') | Out-Null Write-Host "Initial ExcludedApps Data:" $ExcludedApps + # if ($UpdateParameters.ContainsKey('ExcludedApps')) { + # if ($ExcludedApps -ne $null) { + # $excludedAppsDict = [ordered]@{} + + # foreach ($property in $ExcludedApps.CimInstanceProperties) { + # $camelCaseName = $property.Name.Substring(0, 1).ToLower() + $property.Name.Substring(1) + # $excludedAppsDict[$camelCaseName] = $property.Value + # } + + # # Convert the hashtable to a dictionary for API submission + # $excludedAppsDictTyped = [System.Collections.Generic.Dictionary[string, bool]]::new() + # foreach ($key in $excludedAppsDict.Keys) { + # $excludedAppsDictTyped.Add($key, $excludedAppsDict[$key]) + # } + + # $UpdateParameters['excludedApps'] = $excludedAppsDictTyped + # } else { + # Write-Host "ExcludedApps is null." + # } + # } else { + # Write-Host "ExcludedApps parameter not found in UpdateParameters." + # } + if ($UpdateParameters.ContainsKey('ExcludedApps')) { if ($ExcludedApps -ne $null) { - $excludedAppsDict = [ordered]@{} - - foreach ($property in $ExcludedApps.CimInstanceProperties) { - $camelCaseName = $property.Name.Substring(0, 1).ToLower() + $property.Name.Substring(1) - $excludedAppsDict[$camelCaseName] = $property.Value - } - - # Convert the hashtable to a dictionary for API submission - $excludedAppsDictTyped = [System.Collections.Generic.Dictionary[string, bool]]::new() - foreach ($key in $excludedAppsDict.Keys) { - $excludedAppsDictTyped.Add($key, $excludedAppsDict[$key]) - } - - $UpdateParameters['excludedApps'] = $excludedAppsDictTyped + # Directly assign the CimInstance to the UpdateParameters without converting + $UpdateParameters['excludedApps'] = $ExcludedApps } else { Write-Host "ExcludedApps is null." } - } else { - Write-Host "ExcludedApps parameter not found in UpdateParameters." } # Print the entire UpdateParameters being sent to the API From 0b9f328f10f37a14d33f6add64092010ef76f6cf Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 08:27:41 -0700 Subject: [PATCH 14/32] fix for excluded apps --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 125 +++--------------- ...MobileAppsWindowsOfficeSuiteApp.schema.mof | 6 +- 2 files changed, 23 insertions(+), 108 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index 8b9a78e64e..ad4600d8fe 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -18,10 +18,6 @@ function Get-TargetResource [System.String] $Description, - [Parameter()] - [System.String] - $Publisher, - [Parameter()] [System.Boolean] $IsFeatured, @@ -34,23 +30,10 @@ function Get-TargetResource [System.String] $InformationUrl, - [Parameter()] - [System.String] - $Owner, - - [Parameter()] - [System.String] - $Developer, - [Parameter()] [System.String] $Notes, - [Parameter()] - [System.String] - [ValidateSet('notPublished', 'processing','published')] - $PublishingState, - [Parameter()] [System.String[]] $RoleScopeTagIds, @@ -221,13 +204,13 @@ function Get-TargetResource $complexCategories += $myCategory } - # $complexExcludedApps = [ordered]@{} - # if ($null -ne $instance.AdditionalProperties.excludedApps) { - # foreach ($property in $instance.AdditionalProperties.excludedApps.CimInstanceProperties) { - # $camelCaseName = $property.Name.Substring(0, 1).ToLower() + $property.Name.Substring(1) - # $complexExcludedApps[$camelCaseName] = $property.Value - # } - # } + $complexExcludedApps = @{} + if ($null -ne $instance.AdditionalProperties.excludedApps) + { + $instance.AdditionalProperties.excludedApps.GetEnumerator() | Foreach-Object { + $complexExcludedApps.Add($_.Key, $_.Value) + } + } $complexLargeIcon = @{} if ($null -ne $instance.LargeIcon.Value) @@ -240,12 +223,9 @@ function Get-TargetResource Id = $instance.Id DisplayName = $instance.DisplayName Description = $instance.Description - Publisher = $instance.Publisher IsFeatured = $instance.IsFeatured PrivacyInformationUrl = $instance.PrivacyInformationUrl InformationUrl = $instance.InformationUrl - Owner = $instance.Owner - Developer = $instance.Developer Notes = $instance.Notes RoleScopeTagIds = $instance.RoleScopeTagIds AutoAcceptEula = $instance.AdditionalProperties.autoAcceptEula @@ -261,7 +241,7 @@ function Get-TargetResource UpdateVersion = $instance.AdditionalProperties.updateVersion OfficeConfigurationXml = $instance.AdditionalProperties.officeConfigurationXml LargeIcon = $complexLargeIcon - ExcludedApps = $instance.AdditionalProperties.excludedApps + ExcludedApps = $complexExcludedApps Categories = $complexCategories Ensure = 'Present' Credential = $Credential @@ -326,10 +306,6 @@ function Set-TargetResource [System.String] $Description, - [Parameter()] - [System.String] - $Publisher, - [Parameter()] [System.Boolean] $IsFeatured, @@ -342,23 +318,10 @@ function Set-TargetResource [System.String] $InformationUrl, - [Parameter()] - [System.String] - $Owner, - - [Parameter()] - [System.String] - $Developer, - [Parameter()] [System.String] $Notes, - [Parameter()] - [System.String] - [ValidateSet('notPublished', 'processing','published')] - $PublishingState, - [Parameter()] [System.String[]] $RoleScopeTagIds, @@ -492,6 +455,9 @@ function Set-TargetResource $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters $CreateParameters.Remove('Id') | Out-Null $CreateParameters.Remove('Categories') | Out-Null + $CreateParameters.Add('Publisher', 'Microsoft') + $CreateParameters.Add('Developer', 'Microsoft') + $CreateParameters.Add('Owner', 'Microsoft') foreach ($key in ($CreateParameters.Clone()).Keys) { @@ -508,7 +474,7 @@ function Set-TargetResource { if ($category.Id) { - $currentCategory = Get-MgBetaDeviceAppManagementMobileAppCategory -CategoryId $category.Id + $currentCategory = Get-MgBetaDeviceAppManagementMobileAppCategory -MobileAppCategoryId $category.Id } else { @@ -520,7 +486,7 @@ function Set-TargetResource throw "Mobile App Category with DisplayName $($category.DisplayName) not found." } - Invoke-MgBetaGraphRequest -Uri "/beta/deviceAppManagement/mobileApps/$($app.Id)/categories/`$ref" -Method 'POST' -Body @{ + Invoke-MgGraphRequest -Uri "/beta/deviceAppManagement/mobileApps/$($app.Id)/categories/`$ref" -Method 'POST' -Body @{ '@odata.id' = "https://graph.microsoft.com/beta/deviceAppManagement/mobileAppCategories/$($currentCategory.Id)" } } @@ -543,47 +509,16 @@ function Set-TargetResource $UpdateParameters.Remove('Id') | Out-Null $UpdateParameters.Remove('Categories') | Out-Null $UpdateParameters.Remove('OfficePlatformArchitecture') | Out-Null - $UpdateParameters.Remove('Developer') | Out-Null - $UpdateParameters.Remove('Owner') | Out-Null - $UpdateParameters.Remove('Publisher') | Out-Null - $UpdateParameters.Remove('RoleScopeTagIds') | Out-Null - Write-Host "Initial ExcludedApps Data:" $ExcludedApps - - # if ($UpdateParameters.ContainsKey('ExcludedApps')) { - # if ($ExcludedApps -ne $null) { - # $excludedAppsDict = [ordered]@{} - - # foreach ($property in $ExcludedApps.CimInstanceProperties) { - # $camelCaseName = $property.Name.Substring(0, 1).ToLower() + $property.Name.Substring(1) - # $excludedAppsDict[$camelCaseName] = $property.Value - # } - - # # Convert the hashtable to a dictionary for API submission - # $excludedAppsDictTyped = [System.Collections.Generic.Dictionary[string, bool]]::new() - # foreach ($key in $excludedAppsDict.Keys) { - # $excludedAppsDictTyped.Add($key, $excludedAppsDict[$key]) - # } - - # $UpdateParameters['excludedApps'] = $excludedAppsDictTyped - # } else { - # Write-Host "ExcludedApps is null." - # } - # } else { - # Write-Host "ExcludedApps parameter not found in UpdateParameters." - # } - - if ($UpdateParameters.ContainsKey('ExcludedApps')) { - if ($ExcludedApps -ne $null) { - # Directly assign the CimInstance to the UpdateParameters without converting - $UpdateParameters['excludedApps'] = $ExcludedApps - } else { - Write-Host "ExcludedApps is null." + + foreach ($key in ($UpdateParameters.Clone()).Keys) + { + if ($null -ne $UpdateParameters.$key -and $UpdateParameters.$key.GetType().Name -like '*CimInstance*') + { + $UpdateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $UpdateParameters.$key } } - # Print the entire UpdateParameters being sent to the API - Write-Host "Now ExcludedApps Data:" $UpdateParameters['excludedApps'] - + $UpdateParameters.Add('@odata.type', '#microsoft.graph.officeSuiteApp') Update-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id -BodyParameter $UpdateParameters [array]$referenceObject = if ($null -ne $currentInstance.Categories.DisplayName) { $currentInstance.Categories.DisplayName } else { ,@() } @@ -651,10 +586,6 @@ function Test-TargetResource [System.String] $Description, - [Parameter()] - [System.String] - $Publisher, - [Parameter()] [System.Boolean] $IsFeatured, @@ -667,23 +598,10 @@ function Test-TargetResource [System.String] $InformationUrl, - [Parameter()] - [System.String] - $Owner, - - [Parameter()] - [System.String] - $Developer, - [Parameter()] [System.String] $Notes, - [Parameter()] - [System.String] - [ValidateSet('notPublished', 'processing','published')] - $PublishingState, - [Parameter()] [System.String[]] $RoleScopeTagIds, @@ -843,6 +761,7 @@ function Test-TargetResource $PSBoundParameters.Remove('LargeIcon') | Out-Null $ValuesToCheck.Remove('Id') | Out-Null + $ValuesToCheck.Remove('OfficePlatformArchitecture') | Out-Null # Cannot be changed after creation $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" @@ -1043,7 +962,7 @@ function Export-TargetResource if ($null -ne $Results.ExcludedApps) { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ExcludedApps' -IsCIMArray:$true + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ExcludedApps' -IsCIMArray:$false } if ($null -ne $Results.LargeIcon) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof index c91163da06..a21a984fca 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof @@ -46,14 +46,10 @@ class MSFT_IntuneMobileAppsWindowsOfficeSuiteApp : OMI_BaseResource [Write, Description("The unique identifier for an entity. Read-only. Inherited from mobileApp object.")] String Id; [Write, Description("The description of the app. Inherited from mobileApp.")] String Description; - [Write, Description("The publisher of the app. Inherited from mobileApp.")] String Publisher; [Write, Description("The value indicating whether the app is marked as featured by the admin. Inherited from mobileApp.")] Boolean IsFeatured; [Write, Description("The privacy statement Url. Inherited from mobileApp.")] String PrivacyInformationUrl; [Write, Description("The InformationUrl of the app. Inherited from mobileApp.")] String InformationUrl; - [Write, Description("The owner of the app. Inherited from mobileApp.")] String Owner; - [Write, Description("The dewveloper of the app. Inherited from mobileApp.")] String Developer; [Write, Description("Notes for the app. Inherited from mobileApp.")] String Notes; - [Write, Description("The publishing state for the app. The app cannot be assigned unless the app is published. Inherited from mobileApp."), ValueMap{"notPublished", "processing","published"}, Values{"notPublished", "processing", "published"}] String PublishingState; [Write, Description("List of Scope Tag IDs for mobile app.")] String RoleScopeTagIds[]; [Write, Description("The icon for this app."), EmbeddedInstance("MSFT_DeviceManagementMimeContent")] String LargeIcon; [Write, Description("Specifies if the EULA is accepted automatically on the end user's device.")] Boolean AutoAcceptEula; @@ -61,7 +57,7 @@ class MSFT_IntuneMobileAppsWindowsOfficeSuiteApp : OMI_BaseResource [Write, Description("Indicates whether shared computer activation is used for Office installations.")] Boolean UseSharedComputerActivation; [Write, Description("Specifies the update channel for the Office 365 app suite, such as 'Current' or 'Deferred'.")] String UpdateChannel; [Write, Description("Specifies the default file format type for Office apps, such as 'OfficeOpenXMLFormat' or 'OfficeOpenDocumentFormat'.")] String OfficeSuiteAppDefaultFileFormat; - [Write, Description("The architecture of the Office installation (e.g., 'X86', 'X64', or 'Arm64').")] String OfficePlatformArchitecture; + [Write, Description("The architecture of the Office installation (e.g., 'X86', 'X64', or 'Arm64'). Cannot be changed after creation.")] String OfficePlatformArchitecture; [Write, Description("Specifies the locales to be installed when the Office 365 apps are deployed. Uses the standard RFC 5646 format (e.g., 'en-US', 'fr-FR').")] String LocalesToInstall[]; [Write, Description("Specifies the display level of the installation progress for Office apps. Use 'Full' to display the installation UI, or 'None' for a silent installation.")] String InstallProgressDisplayLevel; [Write, Description("Indicates whether older versions of Office should be uninstalled when deploying the Office 365 app suite.")] Boolean ShouldUninstallOlderVersionsOfOffice; From 33cf7c8ace29bd68bebfbee2823129164dad0bbf Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 08:59:03 -0700 Subject: [PATCH 15/32] remove large icon because not supported for office windows suite app --- ...IntuneMobileAppsWindowsOfficeSuiteApp.psm1 | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 index ad4600d8fe..f10634ed10 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.psm1 @@ -103,9 +103,9 @@ function Get-TargetResource [Microsoft.Management.Infrastructure.CimInstance[]] $Assignments, - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $LargeIcon, + # [Parameter()] + # [Microsoft.Management.Infrastructure.CimInstance] + # $LargeIcon, #endregion @@ -212,12 +212,12 @@ function Get-TargetResource } } - $complexLargeIcon = @{} - if ($null -ne $instance.LargeIcon.Value) - { - $complexLargeIcon.Add('Value', [System.Convert]::ToBase64String($instance.LargeIcon.Value)) - $complexLargeIcon.Add('Type', $instance.LargeIcon.Type) - } + # $complexLargeIcon = @{} + # if ($null -ne $instance.LargeIcon.Value) + # { + # $complexLargeIcon.Add('Value', [System.Convert]::ToBase64String($instance.LargeIcon.Value)) + # $complexLargeIcon.Add('Type', $instance.LargeIcon.Type) + # } $results = @{ Id = $instance.Id @@ -240,7 +240,7 @@ function Get-TargetResource TargetVersion = $instance.AdditionalProperties.targetVersion UpdateVersion = $instance.AdditionalProperties.updateVersion OfficeConfigurationXml = $instance.AdditionalProperties.officeConfigurationXml - LargeIcon = $complexLargeIcon + # LargeIcon = $complexLargeIcon ExcludedApps = $complexExcludedApps Categories = $complexCategories Ensure = 'Present' @@ -391,9 +391,9 @@ function Set-TargetResource [Microsoft.Management.Infrastructure.CimInstance[]] $Assignments, - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $LargeIcon, + # [Parameter()] + # [Microsoft.Management.Infrastructure.CimInstance] + # $LargeIcon, #endregion @@ -561,7 +561,7 @@ function Set-TargetResource } elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') { - Write-Host "Remove the Intune MacOS Lob App with Id {$($currentInstance.Id)}" + Write-Host "Remove the Intune Windows Office Suite App with Id {$($currentInstance.Id)}" Remove-MgBetaDeviceAppManagementMobileApp -MobileAppId $currentInstance.Id -Confirm:$false } } @@ -671,9 +671,9 @@ function Test-TargetResource [Microsoft.Management.Infrastructure.CimInstance[]] $Assignments, - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $LargeIcon, + # [Parameter()] + # [Microsoft.Management.Infrastructure.CimInstance] + # $LargeIcon, #endregion @@ -757,8 +757,8 @@ function Test-TargetResource # Prevent screen from filling up with the LargeIcon value # Comparison will already be done because it's a CimInstance - $CurrentValues.Remove('LargeIcon') | Out-Null - $PSBoundParameters.Remove('LargeIcon') | Out-Null + # $CurrentValues.Remove('LargeIcon') | Out-Null + # $PSBoundParameters.Remove('LargeIcon') | Out-Null $ValuesToCheck.Remove('Id') | Out-Null $ValuesToCheck.Remove('OfficePlatformArchitecture') | Out-Null # Cannot be changed after creation @@ -912,21 +912,21 @@ function Export-TargetResource } } - if ($null -ne $Results.LargeIcon) - { - $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` - -ComplexObject $Results.LargeIcon ` - -CIMInstanceName 'DeviceManagementMimeContent' - - if (-not [System.String]::IsNullOrWhiteSpace($complexTypeStringResult)) - { - $Results.LargeIcon = $complexTypeStringResult - } - else - { - $Results.Remove('LargeIcon') | Out-Null - } - } + # if ($null -ne $Results.LargeIcon) + # { + # $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + # -ComplexObject $Results.LargeIcon ` + # -CIMInstanceName 'DeviceManagementMimeContent' + + # if (-not [System.String]::IsNullOrWhiteSpace($complexTypeStringResult)) + # { + # $Results.LargeIcon = $complexTypeStringResult + # } + # else + # { + # $Results.Remove('LargeIcon') | Out-Null + # } + # } if ($null -ne $Results.Assignments) { @@ -965,10 +965,10 @@ function Export-TargetResource $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ExcludedApps' -IsCIMArray:$false } - if ($null -ne $Results.LargeIcon) - { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'LargeIcon' -IsCIMArray:$false - } + # if ($null -ne $Results.LargeIcon) + # { + # $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'LargeIcon' -IsCIMArray:$false + # } if ($null -ne $Results.Assignments) { From daf2bd68a020a09a34290110efb2bd2cd9b0ec3b Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 11:19:15 -0700 Subject: [PATCH 16/32] remove large icon from mof --- .../MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof index a21a984fca..9d07d216db 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp/MSFT_IntuneMobileAppsWindowsOfficeSuiteApp.schema.mof @@ -51,7 +51,6 @@ class MSFT_IntuneMobileAppsWindowsOfficeSuiteApp : OMI_BaseResource [Write, Description("The InformationUrl of the app. Inherited from mobileApp.")] String InformationUrl; [Write, Description("Notes for the app. Inherited from mobileApp.")] String Notes; [Write, Description("List of Scope Tag IDs for mobile app.")] String RoleScopeTagIds[]; - [Write, Description("The icon for this app."), EmbeddedInstance("MSFT_DeviceManagementMimeContent")] String LargeIcon; [Write, Description("Specifies if the EULA is accepted automatically on the end user's device.")] Boolean AutoAcceptEula; [Write, Description("The Product IDs that represent the Office 365 Suite SKU, such as 'O365ProPlusRetail' or 'VisioProRetail'.")] String ProductIds[]; [Write, Description("Indicates whether shared computer activation is used for Office installations.")] Boolean UseSharedComputerActivation; From f1ede66f6b51ee7195212bbde2e7231c5ba8d009 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 15:34:03 -0700 Subject: [PATCH 17/32] add tests --- ...eMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 261 ++++++++++++++---- 1 file changed, 208 insertions(+), 53 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 index 780e0f343d..189cbc3534 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -31,128 +31,262 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Confirm-M365DSCDependencies -MockWith { } + Mock -CommandName Get-PSSession -MockWith { + } + + Mock -CommandName Remove-PSSession -MockWith { + } + Mock -CommandName New-M365DSCConnection -MockWith { return "Credentials" } - ##TODO - Mock any Remove/Set/New cmdlets + Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { + } + Mock -CommandName New-MgBetaDeviceAppManagementMobileApp -MockWith { + } + Mock -CommandName Update-MgBetaDeviceAppManagementMobileApp -MockWith { + } + Mock -CommandName Remove-MgBetaDeviceAppManagementMobileApp -MockWith { + } + + Mock -CommandName Update-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{} # 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 instance should exist but it DOES NOT" -Fixture { + Context -Name "1. The instance should exist but it DOES NOT" -Fixture { BeforeAll { $testParams = @{ - ##TODO - Add Parameters - Ensure = 'Present' - Credential = $Credential; + Id = "8d027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and later" + Developer = "Contoso" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + InformationUrl = "" + IsFeatured = $False + MinimumSupportedOperatingSystem = [CimInstance]( + New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ + v11_0 = $true + } -ClientOnly) + Notes = "" + Owner = "" + PrivacyInformationUrl = "" + Publisher = "Contoso" + RoleScopeTagIds = @() + Ensure = 'Present' + Credential = $Credential } - ##TODO - Mock the Get-Cmdlet to return $null - Mock -CommandName Get-Cmdlet -MockWith { + Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { return $null } } - It 'Should return Values from the Get method' { + + It '1.1 Should return Values from the Get method' { (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' } - It 'Should return false from the Test method' { + It '1.2 Should return false from the Test method' { Test-TargetResource @testParams | Should -Be $false } - - It 'Should create a new instance from the Set method' { - ##TODO - Replace the New-Cmdlet by the appropriate one + It '1.3 Should create a new instance from the Set method' { Set-TargetResource @testParams - Should -Invoke -CommandName New-Cmdlet -Exactly 1 + Should -Invoke -CommandName New-MgBetaDeviceAppManagementMobileApp -Exactly 1 } } - Context -Name "The instance exists but it SHOULD NOT" -Fixture { + Context -Name "2. The instance exists but it SHOULD NOT" -Fixture { BeforeAll { $testParams = @{ - ##TODO - Add Parameters - Ensure = 'Absent' - Credential = $Credential; + Id = "ad027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and later" + Developer = "Contoso" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + InformationUrl = "" + IsFeatured = $False + MinimumSupportedOperatingSystem = [CimInstance]( + New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ + v11_0 = $true + } -ClientOnly) + Notes = "" + Owner = "" + PrivacyInformationUrl = "" + Publisher = "Contoso" + RoleScopeTagIds = @() + IgnoreVersionDetection = $True + Ensure = 'Absent' + Credential = $Credential } - ##TODO - Mock the Get-Cmdlet to return an instance - Mock -CommandName Get-Cmdlet -MockWith { + Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { return @{ - + Id = "ad027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and laterr" + Developer = "Contoso" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + InformationUrl = "" + IsFeatured = $False + Notes = "" + Owner = "" + PrivacyInformationUrl = "" + Publisher = "Contoso" + PublishingState = "published" + RoleScopeTagIds = @() + IgnoreVersionDetection = $True + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.officeSuiteApp' + minimumSupportedOperatingSystem = @{ + v11_0 = $true + } + } + Ensure = 'Present' } } + + Mock -CommandName Get-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{ + return $null + } } - It 'Should return Values from the Get method' { + + It '2.1 Should return Values from the Get method' { (Get-TargetResource @testParams).Ensure | Should -Be 'Present' } - It 'Should return false from the Test method' { + It '2.2 Should return false from the Test method' { Test-TargetResource @testParams | Should -Be $false } - - It 'Should remove the instance from the Set method' { + It '2.3 Should remove the instance from the Set method' { Set-TargetResource @testParams - ##TODO - Replace the Remove-Cmdlet by the appropriate one - Should -Invoke -CommandName Remove-Cmdlet -Exactly 1 + Should -Invoke -CommandName Remove-MgBetaDeviceAppManagementMobileApp -Exactly 1 } } - Context -Name "The instance exists and values are already in the desired state" -Fixture { + Context -Name "3. The instance exists and values are already in the desired state" -Fixture { BeforeAll { $testParams = @{ - ##TODO - Add Parameters - Ensure = 'Present' - Credential = $Credential; + Id = "8d027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and later" + Developer = "Contoso" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + InformationUrl = "" + IsFeatured = $False + MinimumSupportedOperatingSystem = [CimInstance]( + New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ + v11_0 = $true + } -ClientOnly) + Notes = "" + Owner = "" + PrivacyInformationUrl = "" + Publisher = "Contoso" + RoleScopeTagIds = @() + Ensure = 'Present' + Credential = $Credential; } - ##TODO - Mock the Get-Cmdlet to return the desired values - Mock -CommandName Get-Cmdlet -MockWith { + Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { return @{ - + Id = "8d027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and later" + Developer = "Contoso" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + InformationUrl = "" + IsFeatured = $False + Notes = "" + Owner = "" + PrivacyInformationUrl = "" + Publisher = "Contoso" + PublishingState = "published" + RoleScopeTagIds = @() + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.officeSuiteApp' + minimumSupportedOperatingSystem = @{ + v11_0 = $true + } + } } } + Mock -CommandName Get-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{ + return $null + } } - It 'Should return true from the Test method' { + It '3.0 Should return true from the Test method' { Test-TargetResource @testParams | Should -Be $true } } - Context -Name "The instance exists and values are NOT in the desired state" -Fixture { + Context -Name "4. The instance exists and values are NOT in the desired state" -Fixture { BeforeAll { $testParams = @{ - ##TODO - Add Parameters - Ensure = 'Present' - Credential = $Credential; + Id = "8d027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and later" + Developer = "Contoso" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + InformationUrl = "" + IsFeatured = $False + MinimumSupportedOperatingSystem = [CimInstance]( + New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ + v11_0 = $true + } -ClientOnly) + Notes = "" + Owner = "" + PrivacyInformationUrl = "" + Publisher = "Contoso" + RoleScopeTagIds = @() + Ensure = 'Present' + Credential = $Credential; } - ##TODO - Mock the Get-Cmdlet to return a drift - Mock -CommandName Get-Cmdlet -MockWith { + Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { return @{ - + Id = "8d027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and later" + Developer = "Contoso" + DisplayName = "Microsoft 365 Apps for Windows 10 and later drift" + InformationUrl = "" + IsFeatured = $False + Notes = "" + Owner = "" + PrivacyInformationUrl = "" + Publisher = "Contoso" + PublishingState = "published" + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.officeSuiteApp' + minimumSupportedOperatingSystem = @{ + v11_0 = $true + } + } } } + Mock -CommandName Get-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{ + return $null + } } - It 'Should return Values from the Get method' { + It '4.1 Should return Values from the Get method' { (Get-TargetResource @testParams).Ensure | Should -Be 'Present' } - - It 'Should return false from the Test method' { + It '4.2 Should return false from the Test method' { Test-TargetResource @testParams | Should -Be $false } - - It 'Should call the Set method' { + It '4.3 Should call the Set method' { Set-TargetResource @testParams - ##TODO - Replace the Update-Cmdlet by the appropriate one - Should -Invoke -CommandName Update-Cmdlet -Exactly 1 + Should -Invoke -CommandName Update-MgBetaDeviceAppManagementMobileApp -Exactly 1 } } - Context -Name 'ReverseDSC Tests' -Fixture { + Context -Name '5. ReverseDSC Tests' -Fixture { BeforeAll { $Global:CurrentModeIsExport = $true $Global:PartialExportFileName = "$(New-Guid).partial.ps1" @@ -160,14 +294,35 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Credential = $Credential; } - ##TODO - Mock the Get-Cmdlet to return an instance - Mock -CommandName Get-Cmdlet -MockWith { + Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { return @{ - + Id = "8d027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and later" + Developer = "Contoso" + DisplayName = "Microsoft 365 Apps for Windows 10 and later drift" + InformationUrl = "" + IsFeatured = $False + Notes = "" + Owner = "" + PrivacyInformationUrl = "" + Publisher = "Contoso" + PublishingState = "published" + RoleScopeTagIds = @() + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.officeSuiteApp' + minimumSupportedOperatingSystem = @{ + v11_0 = $true + } + } } } + Mock -CommandName Get-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{ + return $null + } } - It 'Should Reverse Engineer resource from the Export method' { + + It '5.0 Should Reverse Engineer resource from the Export method' { $result = Export-TargetResource @testParams $result | Should -Not -BeNullOrEmpty } From 5117eefe70f7d65358d7b6bd8f87daf3e1d14af6 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 15:59:15 -0700 Subject: [PATCH 18/32] fix tests --- ...soft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 index 189cbc3534..b1a272ed47 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -67,7 +67,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Id = "8d027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and later" - Developer = "Contoso" DisplayName = "Microsoft 365 Apps for Windows 10 and later" InformationUrl = "" IsFeatured = $False @@ -75,10 +74,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ v11_0 = $true } -ClientOnly) - Notes = "" - Owner = "" PrivacyInformationUrl = "" - Publisher = "Contoso" RoleScopeTagIds = @() Ensure = 'Present' Credential = $Credential From 7fd57884b9dc3181b4926b9f47150a01469e3bab Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 17:01:44 -0700 Subject: [PATCH 19/32] update tests --- ...eMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 181 +++++++++++++----- 1 file changed, 128 insertions(+), 53 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 index b1a272ed47..67ac460a73 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -70,12 +70,26 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { DisplayName = "Microsoft 365 Apps for Windows 10 and later" InformationUrl = "" IsFeatured = $False - MinimumSupportedOperatingSystem = [CimInstance]( - New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ - v11_0 = $true - } -ClientOnly) PrivacyInformationUrl = "" + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) RoleScopeTagIds = @() + Notes = "" Ensure = 'Present' Credential = $Credential } @@ -103,20 +117,29 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Id = "ad027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and later" - Developer = "Contoso" DisplayName = "Microsoft 365 Apps for Windows 10 and later" InformationUrl = "" IsFeatured = $False - MinimumSupportedOperatingSystem = [CimInstance]( - New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ - v11_0 = $true + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false } -ClientOnly) Notes = "" - Owner = "" PrivacyInformationUrl = "" - Publisher = "Contoso" RoleScopeTagIds = @() - IgnoreVersionDetection = $True Ensure = 'Absent' Credential = $Credential } @@ -126,23 +149,29 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Id = "ad027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and laterr" - Developer = "Contoso" DisplayName = "Microsoft 365 Apps for Windows 10 and later" InformationUrl = "" IsFeatured = $False Notes = "" - Owner = "" PrivacyInformationUrl = "" - Publisher = "Contoso" - PublishingState = "published" RoleScopeTagIds = @() - IgnoreVersionDetection = $True - AdditionalProperties = @{ - '@odata.type' = '#microsoft.graph.officeSuiteApp' - minimumSupportedOperatingSystem = @{ - v11_0 = $true - } - } + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) Ensure = 'Present' } } @@ -170,18 +199,28 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Id = "8d027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and later" - Developer = "Contoso" DisplayName = "Microsoft 365 Apps for Windows 10 and later" InformationUrl = "" IsFeatured = $False - MinimumSupportedOperatingSystem = [CimInstance]( - New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ - v11_0 = $true - } -ClientOnly) Notes = "" - Owner = "" PrivacyInformationUrl = "" - Publisher = "Contoso" + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) RoleScopeTagIds = @() Ensure = 'Present' Credential = $Credential; @@ -192,22 +231,39 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Id = "8d027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and later" - Developer = "Contoso" DisplayName = "Microsoft 365 Apps for Windows 10 and later" InformationUrl = "" IsFeatured = $False Notes = "" - Owner = "" PrivacyInformationUrl = "" - Publisher = "Contoso" - PublishingState = "published" RoleScopeTagIds = @() - AdditionalProperties = @{ - '@odata.type' = '#microsoft.graph.officeSuiteApp' - minimumSupportedOperatingSystem = @{ - v11_0 = $true - } - } + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) + Assignments = @( + (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppAssignment -Property @{ + deviceAndAppManagementAssignmentFilterType = 'none' + source = 'direct' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '42c02b60-f28c-4eef-b3e1-973184cc4a6c' + intent = 'required' + } -ClientOnly) + ) + Ensure = 'Present' } } Mock -CommandName Get-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{ @@ -226,18 +282,28 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Id = "8d027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and later" - Developer = "Contoso" DisplayName = "Microsoft 365 Apps for Windows 10 and later" InformationUrl = "" IsFeatured = $False - MinimumSupportedOperatingSystem = [CimInstance]( - New-CimInstance -ClassName MSFT_DeviceManagementMinimumOperatingSystem -Property @{ - v11_0 = $true + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false } -ClientOnly) Notes = "" - Owner = "" PrivacyInformationUrl = "" - Publisher = "Contoso" RoleScopeTagIds = @() Ensure = 'Present' Credential = $Credential; @@ -248,15 +314,28 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Id = "8d027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and later" - Developer = "Contoso" DisplayName = "Microsoft 365 Apps for Windows 10 and later drift" InformationUrl = "" IsFeatured = $False Notes = "" - Owner = "" PrivacyInformationUrl = "" - Publisher = "Contoso" - PublishingState = "published" + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) AdditionalProperties = @{ '@odata.type' = '#microsoft.graph.officeSuiteApp' minimumSupportedOperatingSystem = @{ @@ -295,15 +374,11 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Id = "8d027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and later" - Developer = "Contoso" DisplayName = "Microsoft 365 Apps for Windows 10 and later drift" InformationUrl = "" IsFeatured = $False Notes = "" - Owner = "" PrivacyInformationUrl = "" - Publisher = "Contoso" - PublishingState = "published" RoleScopeTagIds = @() AdditionalProperties = @{ '@odata.type' = '#microsoft.graph.officeSuiteApp' From 2686169279c93649903ae31cc8db16c300d5226f Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 17:22:37 -0700 Subject: [PATCH 20/32] update test failure --- ...eMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 index 67ac460a73..c5c90fe479 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -223,7 +223,16 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } -ClientOnly) RoleScopeTagIds = @() Ensure = 'Present' - Credential = $Credential; + Credential = $Credential + Assignments = @( + (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppAssignment -Property @{ + deviceAndAppManagementAssignmentFilterType = 'none' + source = 'direct' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '42c02b60-f28c-4eef-b3e1-973184cc4a6c' + intent = 'required' + } -ClientOnly) + ) } Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { @@ -254,6 +263,8 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { infoPath = $true excel = $false } -ClientOnly) + Ensure = 'Present' + Credential = $Credential Assignments = @( (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppAssignment -Property @{ deviceAndAppManagementAssignmentFilterType = 'none' @@ -263,7 +274,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { intent = 'required' } -ClientOnly) ) - Ensure = 'Present' } } Mock -CommandName Get-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{ @@ -380,6 +390,23 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Notes = "" PrivacyInformationUrl = "" RoleScopeTagIds = @() + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) AdditionalProperties = @{ '@odata.type' = '#microsoft.graph.officeSuiteApp' minimumSupportedOperatingSystem = @{ From a317433674b6e8b334cf15fa255fecf5e4c322a7 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 17:47:24 -0700 Subject: [PATCH 21/32] fix test --- .../1-Create.ps1 | 38 ++++++- ...eMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 107 ++++++++---------- 2 files changed, 85 insertions(+), 60 deletions(-) diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 index b516274848..6dae38e4d8 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 @@ -18,9 +18,45 @@ Configuration Example [System.String] $CertificateThumbprint ) + Import-DscResource -ModuleName Microsoft365DSC node localhost { - + IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-TeamsForBusinessInstaller" + { + Id = "8d027f94-0682-431e-97c1-827d1879fa79"; + Description = "TeamsForBusinessInstaller"; + Developer = "Contoso"; + DisplayName = "TeamsForBusinessInstaller"; + Ensure = "Present"; + InformationUrl = ""; + IsFeatured = $False; + MinimumSupportedOperatingSystem = MSFT_DeviceManagementMinimumOperatingSystem{ + v11_0 = $true + } + Notes = ""; + Owner = ""; + PrivacyInformationUrl = ""; + Publisher = "Contoso"; + Assignments = @( + MSFT_DeviceManagementMobileAppAssignment{ + groupDisplayName = 'All devices' + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.allDevicesAssignmentTarget' + intent = 'required' + } + MSFT_DeviceManagementMobileAppAssignment{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '57b5e81c-85bb-4644-a4fd-33b03e451c89' + intent = 'required' + } + ); + Categories = @( + MSFT_DeviceManagementMobileAppCategory { + Id = '1bff2652-03ec-4a48-941c-152e93736515' + DisplayName = 'Kajal 3' + }); + } } } diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 index c5c90fe479..5cbb2b37f8 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -194,8 +194,40 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } Context -Name "3. The instance exists and values are already in the desired state" -Fixture { - BeforeAll { - $testParams = @{ + BeforeAll { + $testParams = @{ + Id = "8d027f94-0682-431e-97c1-827d1879fa79" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and later" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + InformationUrl = "" + IsFeatured = $False + Notes = "" + PrivacyInformationUrl = "" + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) + RoleScopeTagIds = @() + Ensure = 'Present' + Credential = $Credential + } + + Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { + return @{ Id = "8d027f94-0682-431e-97c1-827d1879fa79" Categories = @() Description = "Microsoft 365 Apps for Windows 10 and later" @@ -222,70 +254,27 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { excel = $false } -ClientOnly) RoleScopeTagIds = @() - Ensure = 'Present' - Credential = $Credential - Assignments = @( - (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppAssignment -Property @{ - deviceAndAppManagementAssignmentFilterType = 'none' - source = 'direct' - dataType = '#microsoft.graph.groupAssignmentTarget' - groupId = '42c02b60-f28c-4eef-b3e1-973184cc4a6c' - intent = 'required' - } -ClientOnly) - ) - } - - Mock -CommandName Get-MgBetaDeviceAppManagementMobileApp -MockWith { - return @{ - Id = "8d027f94-0682-431e-97c1-827d1879fa79" - Categories = @() - Description = "Microsoft 365 Apps for Windows 10 and later" - DisplayName = "Microsoft 365 Apps for Windows 10 and later" - InformationUrl = "" - IsFeatured = $False - Notes = "" - PrivacyInformationUrl = "" - RoleScopeTagIds = @() - ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ - teams = $false - sharePointDesigner = $true - powerPoint = $false - outlook = $false - groove = $true - word = $false - lync = $true - oneNote = $false - oneDrive = $false - publisher = $false - bing = $false - visio = $false - access = $false - infoPath = $true - excel = $false - } -ClientOnly) - Ensure = 'Present' - Credential = $Credential - Assignments = @( - (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppAssignment -Property @{ - deviceAndAppManagementAssignmentFilterType = 'none' - source = 'direct' - dataType = '#microsoft.graph.groupAssignmentTarget' - groupId = '42c02b60-f28c-4eef-b3e1-973184cc4a6c' - intent = 'required' - } -ClientOnly) - ) + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.officeSuiteApp' + minimumSupportedOperatingSystem = @{ + v11_0 = $true + } } - } - Mock -CommandName Get-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{ - return $null + Ensure = 'Present' } } - It '3.0 Should return true from the Test method' { - Test-TargetResource @testParams | Should -Be $true + # Remove Assignments logic for now as we debug this part + Mock -CommandName Get-MgBetaDeviceAppManagementMobileAppAssignment -MockWith{ + return $null } } + It '3.0 Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + Context -Name "4. The instance exists and values are NOT in the desired state" -Fixture { BeforeAll { $testParams = @{ From 3fb01c6d2d43c5e0f31fd5ba47dd06387cae2e77 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 17:59:10 -0700 Subject: [PATCH 22/32] update create ps1 --- .../1-Create.ps1 | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 index 6dae38e4d8..bbcca611da 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 @@ -19,44 +19,44 @@ Configuration Example $CertificateThumbprint ) - Import-DscResource -ModuleName Microsoft365DSC + # Import-DscResource -ModuleName Microsoft365DSC node localhost { - IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-TeamsForBusinessInstaller" - { - Id = "8d027f94-0682-431e-97c1-827d1879fa79"; - Description = "TeamsForBusinessInstaller"; - Developer = "Contoso"; - DisplayName = "TeamsForBusinessInstaller"; - Ensure = "Present"; - InformationUrl = ""; - IsFeatured = $False; - MinimumSupportedOperatingSystem = MSFT_DeviceManagementMinimumOperatingSystem{ - v11_0 = $true - } - Notes = ""; - Owner = ""; - PrivacyInformationUrl = ""; - Publisher = "Contoso"; - Assignments = @( - MSFT_DeviceManagementMobileAppAssignment{ - groupDisplayName = 'All devices' - deviceAndAppManagementAssignmentFilterType = 'none' - dataType = '#microsoft.graph.allDevicesAssignmentTarget' - intent = 'required' - } - MSFT_DeviceManagementMobileAppAssignment{ - deviceAndAppManagementAssignmentFilterType = 'none' - dataType = '#microsoft.graph.groupAssignmentTarget' - groupId = '57b5e81c-85bb-4644-a4fd-33b03e451c89' - intent = 'required' - } - ); - Categories = @( - MSFT_DeviceManagementMobileAppCategory { - Id = '1bff2652-03ec-4a48-941c-152e93736515' - DisplayName = 'Kajal 3' - }); - } + # IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-TeamsForBusinessInstaller" + # { + # Id = "8d027f94-0682-431e-97c1-827d1879fa79"; + # Description = "TeamsForBusinessInstaller"; + # Developer = "Contoso"; + # DisplayName = "TeamsForBusinessInstaller"; + # Ensure = "Present"; + # InformationUrl = ""; + # IsFeatured = $False; + # MinimumSupportedOperatingSystem = MSFT_DeviceManagementMinimumOperatingSystem{ + # v11_0 = $true + # } + # Notes = ""; + # Owner = ""; + # PrivacyInformationUrl = ""; + # Publisher = "Contoso"; + # Assignments = @( + # MSFT_DeviceManagementMobileAppAssignment{ + # groupDisplayName = 'All devices' + # deviceAndAppManagementAssignmentFilterType = 'none' + # dataType = '#microsoft.graph.allDevicesAssignmentTarget' + # intent = 'required' + # } + # MSFT_DeviceManagementMobileAppAssignment{ + # deviceAndAppManagementAssignmentFilterType = 'none' + # dataType = '#microsoft.graph.groupAssignmentTarget' + # groupId = '57b5e81c-85bb-4644-a4fd-33b03e451c89' + # intent = 'required' + # } + # ); + # Categories = @( + # MSFT_DeviceManagementMobileAppCategory { + # Id = '1bff2652-03ec-4a48-941c-152e93736515' + # DisplayName = 'Kajal 3' + # }); + # } } } From ac3712b60b5d3d24bab11c89b1640d6c0502c9f8 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 18:14:26 -0700 Subject: [PATCH 23/32] update 3rd test --- ...eMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 36 ++----------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 index 5cbb2b37f8..cf98006de8 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -204,23 +204,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { IsFeatured = $False Notes = "" PrivacyInformationUrl = "" - ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ - teams = $false - sharePointDesigner = $true - powerPoint = $false - outlook = $false - groove = $true - word = $false - lync = $true - oneNote = $false - oneDrive = $false - publisher = $false - bing = $false - visio = $false - access = $false - infoPath = $true - excel = $false - } -ClientOnly) + ExcludedApps = @() RoleScopeTagIds = @() Ensure = 'Present' Credential = $Credential @@ -236,23 +220,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { IsFeatured = $False Notes = "" PrivacyInformationUrl = "" - ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ - teams = $false - sharePointDesigner = $true - powerPoint = $false - outlook = $false - groove = $true - word = $false - lync = $true - oneNote = $false - oneDrive = $false - publisher = $false - bing = $false - visio = $false - access = $false - infoPath = $true - excel = $false - } -ClientOnly) + ExcludedApps = @() RoleScopeTagIds = @() AdditionalProperties = @{ '@odata.type' = '#microsoft.graph.officeSuiteApp' From 009b0e16d0ec1769d6b400c2aa017cd2d1c0f28a Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 18:28:36 -0700 Subject: [PATCH 24/32] update 3rd test --- ...t365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 index cf98006de8..e27aafd815 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -222,12 +222,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { PrivacyInformationUrl = "" ExcludedApps = @() RoleScopeTagIds = @() - AdditionalProperties = @{ - '@odata.type' = '#microsoft.graph.officeSuiteApp' - minimumSupportedOperatingSystem = @{ - v11_0 = $true - } - } + AdditionalProperties = @{} Ensure = 'Present' } } From 9afd258bbf9f8aa0b6174a318acdb7a99aa1ff90 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 18:30:21 -0700 Subject: [PATCH 25/32] update 3rd test --- ...65DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 index e27aafd815..ff169134f0 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneMobileAppsWindowsOfficeSuiteApp.Tests.ps1 @@ -204,7 +204,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { IsFeatured = $False Notes = "" PrivacyInformationUrl = "" - ExcludedApps = @() RoleScopeTagIds = @() Ensure = 'Present' Credential = $Credential @@ -220,9 +219,13 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { IsFeatured = $False Notes = "" PrivacyInformationUrl = "" - ExcludedApps = @() RoleScopeTagIds = @() - AdditionalProperties = @{} + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.officeSuiteApp' + minimumSupportedOperatingSystem = @{ + v11_0 = $true + } + } Ensure = 'Present' } } From b9dce320c88cc32e0b60f69b8b0613f8153189c5 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 18:56:28 -0700 Subject: [PATCH 26/32] update examples --- .../1-Create.ps1 | 79 ++++++++++--------- .../2-Update.ps1 | 45 ++++++++++- .../3-Remove.ps1 | 8 +- 3 files changed, 94 insertions(+), 38 deletions(-) diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 index bbcca611da..8c29f5a67e 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 @@ -22,41 +22,48 @@ Configuration Example # Import-DscResource -ModuleName Microsoft365DSC node localhost { - # IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-TeamsForBusinessInstaller" - # { - # Id = "8d027f94-0682-431e-97c1-827d1879fa79"; - # Description = "TeamsForBusinessInstaller"; - # Developer = "Contoso"; - # DisplayName = "TeamsForBusinessInstaller"; - # Ensure = "Present"; - # InformationUrl = ""; - # IsFeatured = $False; - # MinimumSupportedOperatingSystem = MSFT_DeviceManagementMinimumOperatingSystem{ - # v11_0 = $true - # } - # Notes = ""; - # Owner = ""; - # PrivacyInformationUrl = ""; - # Publisher = "Contoso"; - # Assignments = @( - # MSFT_DeviceManagementMobileAppAssignment{ - # groupDisplayName = 'All devices' - # deviceAndAppManagementAssignmentFilterType = 'none' - # dataType = '#microsoft.graph.allDevicesAssignmentTarget' - # intent = 'required' - # } - # MSFT_DeviceManagementMobileAppAssignment{ - # deviceAndAppManagementAssignmentFilterType = 'none' - # dataType = '#microsoft.graph.groupAssignmentTarget' - # groupId = '57b5e81c-85bb-4644-a4fd-33b03e451c89' - # intent = 'required' - # } - # ); - # Categories = @( - # MSFT_DeviceManagementMobileAppCategory { - # Id = '1bff2652-03ec-4a48-941c-152e93736515' - # DisplayName = 'Kajal 3' - # }); - # } + IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-Microsoft 365 Apps for Windows 10 and later" + { + Id = "8e683524-4ec1-4813-bb3e-6256b2f293d" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and laterr" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + Ensure = "Present"; + InformationUrl = ""; + IsFeatured = $False; + Notes = "" + PrivacyInformationUrl = "" + RoleScopeTagIds = @() + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) + Assignments = @( + MSFT_DeviceManagementMobileAppAssignment{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '42c02b60-f28c-4eef-b3e1-973184cc4a6c' + intent = 'required' + } + ); + Categories = @( + MSFT_DeviceManagementMobileAppCategory { + Id = '8e683524-4ec1-4813-bb3e-6256b2f293d8' + DisplayName = 'Productivity' + }); + } } } diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 index b516274848..58e03f975d 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 @@ -18,9 +18,52 @@ Configuration Example [System.String] $CertificateThumbprint ) + Import-DscResource -ModuleName Microsoft365DSC node localhost { - + IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-Microsoft 365 Apps for Windows 10 and later" + { + Id = "8e683524-4ec1-4813-bb3e-6256b2f293d" + Categories = @() + Description = "Microsoft 365 Apps for Windows 10 and laterr" + DisplayName = "Microsoft 365 Apps for Windows 10 and later" + Ensure = "Present"; + InformationUrl = ""; + IsFeatured = $False; + Notes = "" + PrivacyInformationUrl = "" + RoleScopeTagIds = @() + ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ + teams = $false + sharePointDesigner = $true + powerPoint = $false + outlook = $false + groove = $true + word = $false + lync = $true + oneNote = $false + oneDrive = $false + publisher = $false + bing = $false + visio = $false + access = $false + infoPath = $true + excel = $false + } -ClientOnly) + Assignments = @( + MSFT_DeviceManagementMobileAppAssignment{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '42c02b60-f28c-4eef-b3e1-973184cc4a6c' + intent = 'required' + } + ); + Categories = @( + MSFT_DeviceManagementMobileAppCategory { + Id = '8e683524-4ec1-4813-bb3e-6256b2f293d8' + DisplayName = 'Productivity' + }); + } } } diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 index b516274848..da1bb82e9b 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 @@ -18,9 +18,15 @@ Configuration Example [System.String] $CertificateThumbprint ) + Import-DscResource -ModuleName Microsoft365DSC node localhost { - + IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-Microsoft 365 Apps for Windows 10 and later" + { + Id = "8e683524-4ec1-4813-bb3e-6256b2f293d8"; + DisplayName = "Microsoft 365 Apps for Windows 10 and later"; + Ensure = "Absent"; + } } } From e3cf023c54b81e870c3cafa74d70ca8922644f53 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 19:05:26 -0700 Subject: [PATCH 27/32] remove duplicate categories --- .../Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 | 1 - .../Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 | 1 - 2 files changed, 2 deletions(-) diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 index 8c29f5a67e..8012f27878 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 @@ -25,7 +25,6 @@ Configuration Example IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-Microsoft 365 Apps for Windows 10 and later" { Id = "8e683524-4ec1-4813-bb3e-6256b2f293d" - Categories = @() Description = "Microsoft 365 Apps for Windows 10 and laterr" DisplayName = "Microsoft 365 Apps for Windows 10 and later" Ensure = "Present"; diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 index 58e03f975d..fe80df05c4 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 @@ -25,7 +25,6 @@ Configuration Example IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-Microsoft 365 Apps for Windows 10 and later" { Id = "8e683524-4ec1-4813-bb3e-6256b2f293d" - Categories = @() Description = "Microsoft 365 Apps for Windows 10 and laterr" DisplayName = "Microsoft 365 Apps for Windows 10 and later" Ensure = "Present"; From 908a878db2d2d8d35eda34fba8376b5ebcda046a Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 19:17:11 -0700 Subject: [PATCH 28/32] include import resource --- .../IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 index 8012f27878..fe80df05c4 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 @@ -19,7 +19,7 @@ Configuration Example $CertificateThumbprint ) - # Import-DscResource -ModuleName Microsoft365DSC + Import-DscResource -ModuleName Microsoft365DSC node localhost { IntuneMobileAppsWindowsOfficeSuiteApp "IntuneMobileAppsWindowsOfficeSuiteApp-Microsoft 365 Apps for Windows 10 and later" From 58362018faa8a6ddbf0cacb34e7463fb6a8c0def Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 19:17:59 -0700 Subject: [PATCH 29/32] update examples --- .../1-Create.ps1 | 17 ----------------- .../2-Update.ps1 | 17 ----------------- 2 files changed, 34 deletions(-) diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 index fe80df05c4..0ae915356e 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 @@ -33,23 +33,6 @@ Configuration Example Notes = "" PrivacyInformationUrl = "" RoleScopeTagIds = @() - ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ - teams = $false - sharePointDesigner = $true - powerPoint = $false - outlook = $false - groove = $true - word = $false - lync = $true - oneNote = $false - oneDrive = $false - publisher = $false - bing = $false - visio = $false - access = $false - infoPath = $true - excel = $false - } -ClientOnly) Assignments = @( MSFT_DeviceManagementMobileAppAssignment{ deviceAndAppManagementAssignmentFilterType = 'none' diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 index fe80df05c4..0ae915356e 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 @@ -33,23 +33,6 @@ Configuration Example Notes = "" PrivacyInformationUrl = "" RoleScopeTagIds = @() - ExcludedApps = (New-CimInstance -ClassName MSFT_DeviceManagementMobileAppExcludedApp -Property @{ - teams = $false - sharePointDesigner = $true - powerPoint = $false - outlook = $false - groove = $true - word = $false - lync = $true - oneNote = $false - oneDrive = $false - publisher = $false - bing = $false - visio = $false - access = $false - infoPath = $true - excel = $false - } -ClientOnly) Assignments = @( MSFT_DeviceManagementMobileAppAssignment{ deviceAndAppManagementAssignmentFilterType = 'none' From 204ad5e956f216a29ed8ce0a66caf7d0f15bd3f1 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Mon, 14 Oct 2024 19:45:40 -0700 Subject: [PATCH 30/32] update macoslosbapp to remove beta as requested --- .../MSFT_IntuneMobileAppsMacOSLobApp.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsMacOSLobApp/MSFT_IntuneMobileAppsMacOSLobApp.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsMacOSLobApp/MSFT_IntuneMobileAppsMacOSLobApp.psm1 index f0e7cd245e..739c2c80d7 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsMacOSLobApp/MSFT_IntuneMobileAppsMacOSLobApp.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneMobileAppsMacOSLobApp/MSFT_IntuneMobileAppsMacOSLobApp.psm1 @@ -450,7 +450,7 @@ function Set-TargetResource throw "Mobile App Category with DisplayName $($category.DisplayName) not found." } - Invoke-MgBetaGraphRequest -Uri "/beta/deviceAppManagement/mobileApps/$($app.Id)/categories/`$ref" -Method 'POST' -Body @{ + Invoke-MgGraphRequest -Uri "/beta/deviceAppManagement/mobileApps/$($app.Id)/categories/`$ref" -Method 'POST' -Body @{ '@odata.id' = "https://graph.microsoft.com/beta/deviceAppManagement/mobileAppCategories/$($currentCategory.Id)" } } From 5cfb6ea215cd3c1436346fb95043dcd6921bac60 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Tue, 15 Oct 2024 09:16:54 -0700 Subject: [PATCH 31/32] add authentication params in examples --- .../IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 | 3 +++ .../IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 | 3 +++ .../IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 | 3 +++ 3 files changed, 9 insertions(+) diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 index 0ae915356e..1eb9c2d9fb 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/1-Create.ps1 @@ -46,6 +46,9 @@ Configuration Example Id = '8e683524-4ec1-4813-bb3e-6256b2f293d8' DisplayName = 'Productivity' }); + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint } } } diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 index 0ae915356e..1eb9c2d9fb 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/2-Update.ps1 @@ -46,6 +46,9 @@ Configuration Example Id = '8e683524-4ec1-4813-bb3e-6256b2f293d8' DisplayName = 'Productivity' }); + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint } } } diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 index da1bb82e9b..8b731ff4ac 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneMobileAppsWindowsOfficeSuiteApp/3-Remove.ps1 @@ -27,6 +27,9 @@ Configuration Example Id = "8e683524-4ec1-4813-bb3e-6256b2f293d8"; DisplayName = "Microsoft 365 Apps for Windows 10 and later"; Ensure = "Absent"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint } } } From 9d17e08dabae8668cbb193f846c2771b10422768 Mon Sep 17 00:00:00 2001 From: "Katherine Hsu (from Dev Box)" Date: Tue, 15 Oct 2024 09:19:18 -0700 Subject: [PATCH 32/32] add update to changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b6d19afb3..f96a9674c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,8 @@ * Migrate to new Settings Catalog cmdlets. * IntuneMobileAppsMacOSLobApp * Initial release +* IntuneMobileAppsWindowsOfficeSuiteApp + * Initial release * PPAdminDLPPolicy * Initial release. * PPDLPPolicyConnectorConfigurations