diff --git a/CHANGELOG.md b/CHANGELOG.md index 0569f040ab..e95f2a5345 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ * IntuneDeviceRemediation * Initial Release FIXES [#4159](https://github.com/microsoft/Microsoft365DSC/issues/4159) +* IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 + * Initial Release + FIXES [#3747](https://github.com/microsoft/Microsoft365DSC/issues/3747) * SPOTenantCdnPolicy * If properties in the tenant are empty then export them as empty arrays instead of null strings, missed while fixing #4658 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.psm1 new file mode 100644 index 0000000000..5e8f837fd0 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.psm1 @@ -0,0 +1,614 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + #region resource generator code + [Parameter()] + [System.String] + $Id, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + [ValidateSet('manual', 'automatic')] + $ApprovalType, + + [Parameter()] + [System.Int32] + $DeploymentDeferralInDays, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + try + { + $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 + + $nullResult = $PSBoundParameters + $nullResult.Ensure = 'Absent' + + $getValue = $null + #region resource generator code + $uri = "/beta/deviceManagement/windowsDriverUpdateProfiles/$Id" + $getValue = (Invoke-MgGraphRequest -Method GET -Uri $uri -SkipHttpErrorCheck).value + + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Intune Windows Update For Business Driver Update Profile for Windows 10 with Id {$Id}" + + if (-Not [string]::IsNullOrEmpty($DisplayName)) + { + $uri = '/beta/deviceManagement/windowsDriverUpdateProfiles' + $getValue = (Invoke-MgGraphRequest -Method GET -Uri $uri).value | Where-Object -FilterScript { + $_.displayName -eq $DisplayName + } + } + } + #endregion + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Intune Windows Update For Business Driver Update Profie for Windows 10 with DisplayName {$DisplayName}" + return $nullResult + } + $Id = $getValue.Id + Write-Verbose -Message "An Intune Windows Update For Business Driver Update Profile for Windows 10 with Id {$Id} and DisplayName {$DisplayName} was found." + + $enumApprovalType = $null + if ($null -ne $getValue.approvalType) + { + $enumApprovalType = $getValue.approvalType.ToString() + } + + $results = @{ + #region resource generator code + ApprovalType = $enumApprovalType + DeploymentDeferralInDays = $getValue.deploymentDeferralInDays + RoleScopeTagIds = $getValue.roleScopeTagIds + Description = $getValue.description + DisplayName = $getValue.displayName + Id = $Id + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + #endregion + } + $uri = "/beta/deviceManagement/windowsDriverUpdateProfiles/$($Id)/assignments" + $assignmentsValues = (Invoke-MgGraphRequest -Method GET -Uri $uri).value + $assignmentResult = @() + foreach ($assignmentEntry in $AssignmentsValues) + { + $assignmentValue = @{ + dataType = $assignmentEntry.Target.'@odata.type' + deviceAndAppManagementAssignmentFilterType = $(if ($null -ne $assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterType) + { + $assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterType + }) + deviceAndAppManagementAssignmentFilterId = $assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterId + groupId = $assignmentEntry.Target.groupId + } + $assignmentResult += $assignmentValue + } + $results.Add('Assignments', $assignmentResult) + + return [System.Collections.Hashtable] $results + } + catch + { + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullResult + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + #region resource generator code + [Parameter()] + [System.String] + $Id, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + [ValidateSet('manual', 'automatic')] + $ApprovalType, + + [Parameter()] + [System.Int32] + $DeploymentDeferralInDays, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [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 + + $BoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + Write-Verbose -Message "Creating an Intune Windows Update For Business Driver Update Profile for Windows 10 with DisplayName {$DisplayName}" + $BoundParameters.Remove('Assignments') | Out-Null + $CreateParameters = ([Hashtable]$BoundParameters).clone() + $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters + $CreateParameters.Remove('Id') | Out-Null + + $keys = (([Hashtable]$CreateParameters).clone()).Keys + foreach ($key in $keys) + { + if ($null -ne $CreateParameters.$key -and $CreateParameters.$key.getType().Name -like '*cimInstance*') + { + $CreateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $CreateParameters.$key + } + } + + #region resource generator code + $uri = '/beta/deviceManagement/windowsDriverUpdateProfiles' + $policy = Invoke-MgGraphRequest -Method POST -Uri $uri -Body $($CreateParameters | ConvertTo-Json) + $assignmentsHash = @() + foreach ($assignment in $Assignments) + { + $assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $Assignment + } + + if ($policy.id) + { + Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $policy.id ` + -Targets $assignmentsHash ` + -Repository 'deviceManagement/windowsDriverUpdateProfiles' + } + #endregion + } + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Updating the Intune Windows Update For Business Driver Update Profile for Windows 10 with Id {$($currentInstance.Id)}" + $BoundParameters.Remove('Assignments') | Out-Null + $UpdateParameters = ([Hashtable]$BoundParameters).clone() + $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters + $UpdateParameters.Remove('ApprovalType') | Out-Null + $UpdateParameters.Remove('Id') | Out-Null + + $keys = (([Hashtable]$UpdateParameters).clone()).Keys + foreach ($key in $keys) + { + if ($null -ne $UpdateParameters.$key -and $UpdateParameters.$key.getType().Name -like '*cimInstance*') + { + $UpdateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $UpdateParameters.$key + } + } + #region resource generator code + $uri = "/beta/deviceManagement/windowsDriverUpdateProfiles/$($currentInstance.Id)" + Invoke-MgGraphRequest -Method PATCH -Uri $uri -Body $($UpdateParameters | ConvertTo-Json) + $assignmentsHash = @() + foreach ($assignment in $Assignments) + { + $assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $assignment + } + Update-DeviceConfigurationPolicyAssignment ` + -DeviceConfigurationPolicyId $currentInstance.Id ` + -Targets $assignmentsHash ` + -Repository 'deviceManagement/windowsDriverUpdateProfiles' + #endregion + } + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Removing the Intune Windows Update For Business Driver Update Profile for Windows 10 with Id {$($currentInstance.Id)}" + #region resource generator code + $uri = "/beta/deviceManagement/windowsDriverUpdateProfiles/$($currentInstance.Id)" + Invoke-MgGraphRequest -Method DELETE -Uri $uri + #endregion + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + #region resource generator code + [Parameter()] + [System.String] + $Id, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + [ValidateSet('manual', 'automatic')] + $ApprovalType, + + [Parameter()] + [System.Int32] + $DeploymentDeferralInDays, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [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 the Intune Windows Update For Business Driver Update Profile for Windows 10 with Id {$Id} and DisplayName {$DisplayName}" + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + + 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*') + { + $source = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $source + + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + + if (-Not $testResult) + { + $testResult = $false + break + } + + $ValuesToCheck.Remove($key) | Out-Null + } + } + + $ValuesToCheck.remove('Id') | Out-Null + $ValuesToCheck.Remove('Credential') | Out-Null + $ValuesToCheck.Remove('ApplicationId') | Out-Null + $ValuesToCheck.Remove('TenantId') | Out-Null + $ValuesToCheck.Remove('ApplicationSecret') | Out-Null + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + 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.String] + $Filter, + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [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 + { + #region resource generator code + # Filter is currently not supported + [array]$getValue = (Invoke-MgGraphRequest -Method GET -Uri '/beta/deviceManagement/windowsDriverUpdateProfiles').value + #endregion + + $i = 1 + $dscContent = '' + if ($getValue.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($config in $getValue) + { + $displayedKey = $config.Id + if (-not [String]::IsNullOrEmpty($config.displayName)) + { + $displayedKey = $config.displayName + } + Write-Host " |---[$i/$($getValue.Count)] $displayedKey" -NoNewline + $params = @{ + Id = $config.Id + DisplayName = $config.DisplayName + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + $Results = Get-TargetResource @Params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + if ($Results.Assignments) + { + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.Assignments -CIMInstanceName DeviceManagementConfigurationPolicyAssignments + if ($complexTypeStringResult) + { + $Results.Assignments = $complexTypeStringResult + } + else + { + $Results.Remove('Assignments') | Out-Null + } + } + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + if ($Results.Assignments) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Assignments' -IsCIMArray:$true + } + + $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 '' + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.schema.mof new file mode 100644 index 0000000000..932a9536b9 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.schema.mof @@ -0,0 +1,30 @@ +[ClassVersion("1.0.0.0")] +class MSFT_DeviceManagementConfigurationPolicyAssignments +{ + [Write, Description("The type of the target assignment."), ValueMap{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget","#microsoft.graph.configurationManagerCollectionAssignmentTarget"}, Values{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget","#microsoft.graph.configurationManagerCollectionAssignmentTarget"}] String dataType; + [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 Id of the filter for the target assignment.")] String deviceAndAppManagementAssignmentFilterId; + [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("The collection Id that is the target of the assignment.(ConfigMgr)")] String collectionId; +}; + +[ClassVersion("1.0.0.0"), FriendlyName("IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10")] +class MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 : OMI_BaseResource +{ + [Write, Description("Id of the Intune policy.")] String Id; + [Key, Description("Display name of the Intune policy.")] String DisplayName; + [Write, Description("Description of the Intune policy.")] String Description; + [Write, Description("Driver update profile approval type. For example, manual or automatic approval. Possible values are: manual, automatic."), ValueMap{"manual","automatic"}, Values{"manual","automatic"}] String ApprovalType; + [Write, Description("Deployment deferral settings in days, only applicable when ApprovalType is set to automatic approval.")] UInt32 DeploymentDeferralInDays; + [Write, Description("List of Scope Tag IDs for the Driver Update entity.")] String RoleScopeTagIds[]; + [Write, Description("Represents the assignment to the Intune policy."), EmbeddedInstance("MSFT_DeviceManagementConfigurationPolicyAssignments")] String Assignments[]; + [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[]; +}; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/readme.md new file mode 100644 index 0000000000..399a17d15f --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/readme.md @@ -0,0 +1,8 @@ + +# IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 + +## Description + +Intune Windows Update For Business Driver Update Profile for Windows 10 + +Please note: Once a policy is created, the `ApprovalType` cannot be changed. A new policy must be created. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/settings.json new file mode 100644 index 0000000000..ceffeec248 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/settings.json @@ -0,0 +1,32 @@ +{ + "resourceName": "IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10", + "description": "This resource configures an Intune Windows Update For Business Driver Update Profile for Windows 10.", + "permissions": { + "graph": { + "delegated": { + "read": [ + { + "name": "DeviceManagementConfiguration.Read.All" + } + ], + "update": [ + { + "name": "DeviceManagementConfiguration.ReadWrite.All" + } + ] + }, + "application": { + "read": [ + { + "name": "DeviceManagementConfiguration.Read.All" + } + ], + "update": [ + { + "name": "DeviceManagementConfiguration.ReadWrite.All" + } + ] + } + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/1-Create.ps1 new file mode 100644 index 0000000000..bb31ab852c --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/1-Create.ps1 @@ -0,0 +1,27 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 'Example' + { + DisplayName = 'Driver Update Example' + Assignments = @() + Description = 'test 2' + approvalType = 'manual' + Ensure = 'Present' + Credential = $Credscredential + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/2-Update.ps1 new file mode 100644 index 0000000000..efe6c0eaa5 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/2-Update.ps1 @@ -0,0 +1,27 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 'Example' + { + DisplayName = 'Driver Update Example' + Assignments = @() + Description = 'test 3' # Updated property + approvalType = 'manual' + Ensure = 'Present' + Credential = $Credscredential + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/3-Remove.ps1 new file mode 100644 index 0000000000..25a5c12adb --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10/3-Remove.ps1 @@ -0,0 +1,25 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 'Example' + { + DisplayName = 'Driver Update Example' + Description = 'test 2' + Ensure = 'Absent' + Credential = $Credscredential + } + } +} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.Tests.ps1 new file mode 100644 index 0000000000..d6dd76dca5 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10.Tests.ps1 @@ -0,0 +1,212 @@ +[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) + +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource "IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10" -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 Get-PSSession -MockWith { + } + + Mock -CommandName Remove-PSSession -MockWith { + } + + Mock -CommandName Invoke-MgGraphRequest -MockWith { + } + + Mock -CommandName Update-DeviceConfigurationPolicyAssignment -MockWith { + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" + } + + # 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 IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + ApprovalType = 'manual' + DisplayName = 'FakeStringValue' + Description = 'FakeStringValue' + Id = 'FakeStringValue' + Ensure = "Present" + Credential = $Credential; + } + + Mock -CommandName Invoke-MgGraphRequest -MockWith { + @{ + value = $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 the group from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Invoke-MgGraphRequest -ParameterFilter { $Method -eq 'POST' } -Exactly 1 + } + } + + Context -Name "The IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + ApprovalType = 'manual' + DisplayName = 'FakeStringValue' + Description = 'FakeStringValue' + Id = 'FakeStringValue' + Ensure = 'Absent' + Credential = $Credential; + } + + Mock -CommandName Invoke-MgGraphRequest -MockWith { + return @{ + value = @( + @{ + ApprovalType = 'manual' + DisplayName = 'FakeStringValue' + Description = 'FakeStringValue' + Id = 'FakeStringValue' + } + ) + } + } + } + + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should Remove the group from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Invoke-MgGraphRequest -ParameterFilter { $Method -eq 'DELETE' } -Exactly 1 + } + } + Context -Name "The IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 Exists and Values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + ApprovalType = 'manual' + DisplayName = 'FakeStringValue' + Description = 'FakeStringValue' + Id = 'FakeStringValue' + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Invoke-MgGraphRequest -MockWith { + return @{ + value = @{ + ApprovalType = 'manual' + DisplayName = 'FakeStringValue' + Description = 'FakeStringValue' + Id = 'FakeStringValue' + } + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The IntuneWindowsUpdateForBusinessDriverUpdateProfileWindows10 exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + ApprovalType = 'manual' + DisplayName = 'FakeStringValue' + Description = 'FakeStringValue' + Id = 'FakeStringValue' + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Invoke-MgGraphRequest -MockWith { + return @{ + value = @{ + ApprovalType = 'manual' + DisplayName = 'FakeStringValue1234' + Description = 'FakeStringValue' + Id = 'FakeStringValue' + } + } + } + } + + 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 + Should -Invoke -CommandName Invoke-MgGraphRequest -ParameterFilter { $Method -eq 'PATCH' } -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential + } + + Mock -CommandName Invoke-MgGraphRequest -MockWith { + return @{ + value = @{ + ApprovalType = 'manual' + DisplayName = 'FakeStringValue' + Description = 'FakeStringValue' + Id = 'FakeStringValue' + } + } + } + } + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope