microsoft / Microsoft365DSC

Manages, configures, extracts and monitors Microsoft 365 tenant configurations
https://aka.ms/M365DSC
MIT License
1.64k stars 505 forks source link

IntuneWindowsAutopilotDeploymentProfileAzureAD{,Hybrid}Joined, IntuneWindowsUpdateForBusinessRingUpdateProfileWindows10: Resources cannot set Assignments property #3892

Closed ricmestre closed 1 year ago

ricmestre commented 1 year ago

Description of the issue

IntuneWindowsAutopilotDeploymentProfileAzureADJoined, IntuneWindowsAutopilotDeploymentProfileAzureADHybridJoined and IntuneWindowsUpdateForBusinessRingUpdateProfileWindows10 resources cannot apply the Assignments property, this seems to be due to an incorrect endpoint used in cmdlet Update-DeviceConfigurationPolicyAssignment (from M365DSCDRGUtil.psm1), according to https://learn.microsoft.com/en-us/graph/api/intune-enrollment-windowsautopilotdeploymentprofileassignment-update?view=graph-rest-beta it should be "deviceManagement/windowsAutopilotDeviceIdentities" instead of "deviceManagement/windowsAutopilotDeploymentProfiles", nevertheless the rest of the URI is also different and works differently since it must used POST for creating the assignments and PATCH to update them, whereas currently the cmdlet only uses POST.

This means that these resources always show up as not being in desired state since Assignments is not correct, I have a diff which I'll create a PR for that solves the problem with the Id property but that's a separate issue.

Minimal reproducer provided with the reference blueprint below, no errors will be displayed while configuration is deployed but Event Viewer shows the following below, but please bear in mind that the apps I use for deployment don't have problems with other resources and they already have scope 'DeviceManagementServiceConfig.ReadWrite.All' assigned which should be sufficient to perform this task so this is not a permission issue from my side.

Error updating data:

{ Response status code does not indicate success: Forbidden (Forbidden). } \ at Update-DeviceConfigurationPolicyAssignment, C:\Program Files\WindowsPowerShell\Modules\Microsoft365DSC\1.23.1108.1\modules\M365DSCDRGUtil.psm1: line 1163
 \ at <ScriptBlock>, <No file>: line 1

@William-Francillette Could you please have a look?

Microsoft 365 DSC Version

1.23.1108.1

Which workloads are affected

other

The DSC configuration

Configuration ConfigureMicrosoft365
{
    Param(
        [Parameter()]
        [PSCredential]$Credential
    )

    Import-DscResource -ModuleName Microsoft365DSC

    $TenantId = $Credential.UserName.Split('@')[1]
    $OrganizationName = $TenantId

    Node localhost
    {
        IntuneWindowsAutopilotDeploymentProfileAzureADJoined "IntuneWindowsAutopilotDeploymentProfileAzureADJoined-IntuneWindowsAutopilotDeploymentProfileAzureADJoined_1"
        {
            Assignments                = @(
                MSFT_DeviceManagementConfigurationPolicyAssignments{
                    dataType = '#microsoft.graph.groupAssignmentTarget'
                    deviceAndAppManagementAssignmentFilterType = 'none'
                    groupId = 'f32b153d-2f22-4f9f-a2dc-70570fdb2b65'
                }
            );
            Credential                 = $Credential;
            Description                = "Windows Autopilot_Azure AD Join_Standard";
            DeviceNameTemplate         = "CMD%SERIAL%";
            DeviceType                 = "windowsPc";
            DisplayName                = "IntuneWindowsAutopilotDeploymentProfileAzureADJoined_1";
            EnableWhiteGlove           = $False;
            Ensure                     = "Present";
            ExtractHardwareHash        = $True;
            Id                         = "b26feb77-3c36-4dd4-a22c-1a70239074dc";
            Language                   = "os-default";
            OutOfBoxExperienceSettings = MSFT_MicrosoftGraphoutOfBoxExperienceSettings1{
                DeviceUsageType = 'singleUser'
                HideEscapeLink = $True
                HideEULA = $True
                HidePrivacySettings = $True
                SkipKeyboardSelectionPage = $True
                UserType = 'standard'
            };
            TenantId                   = $OrganizationName;
        }
    }
}

Verbose logs showing the problem

Error updating data:

{ Response status code does not indicate success: Forbidden (Forbidden). } \ at Update-DeviceConfigurationPolicyAssignment, C:\Program Files\WindowsPowerShell\Modules\Microsoft365DSC\1.23.1108.1\modules\M365DSCDRGUtil.psm1: line 1163
 \ at <ScriptBlock>, <No file>: line 1

Environment Information + PowerShell Version

OsName               : Microsoft Windows 11 Enterprise
OsOperatingSystemSKU : EnterpriseEdition
OsArchitecture       : 64-bit
WindowsVersion       : 2009
WindowsBuildLabEx    : 22621.1.amd64fre.ni_release.220506-1250
OsLanguage           : en-US
OsMuiLanguages       : {en-US, pt-PT}

Name                           Value
----                           -----
PSVersion                      5.1.22621.1778
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.22621.1778
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
William-Francillette commented 1 year ago

I'll have a look tonight but the intune portal uses POST and windowsAutopilotDeploymentProfiles image

Leave it with me I'll have another look tonight and make sure we don't evaluate Id in Test-TargetResource

Thanks

ricmestre commented 1 year ago

I already raised #3893 to remove the Id from $ValuesToCheck :)

ricmestre commented 1 year ago

@William-Francillette It seems that IntuneWindowsUpdateForBusinessRingUpdateProfileWindows10 is also affected by the same problem and Assignments are not applied.

ricmestre commented 1 year ago

What do you know... IntuneDeviceConfigurationPolicyWindows10 is also not working for setting up the Assignments, this one fails with Bad request instead of Forbidden

Error updating data:

{ Response status code does not indicate success: BadRequest (Bad Request). } \ at Update-DeviceConfigurationPolicyAssignment, C:\Program Files\WindowsPowerShell\Modules\Microsoft365DSC\1.23.1108.1\modules\M365DSCDRGUtil.psm1: line 1163
 \ at Set-TargetResource, C:\Program Files\WindowsPowerShell\Modules\Microsoft365DSC\1.23.1108.1\DscResources\MSFT_IntuneDeviceConfigurationPolicyWindows10\MSFT_IntuneDeviceConfigurationPolicyWindows10.psm1: line 3311
William-Francillette commented 1 year ago

Is your group id correct?

ricmestre commented 1 year ago

I wouldn't raise the issue if it wasn't :)

I exported the config from another tenant and replaced the groupIds with the correct Ids from the target tenant, it doesn't matter which ones I choose it always fail, as in the policy is deployed but without setting Assignments.

ricmestre commented 1 year ago

As an example IntuneApplicationControlPolicyWindows10 and IntuneDeviceCompliancePolicyAndroid are working as it should.

William-Francillette commented 1 year ago

ok fair enough, I'll check why those aren't working Assignments worked fine yesterday with IntuneDeviceConfigurationEndpointProtectionPolicyWindows10 and it's using same path as IntuneDeviceConfigurationPolicyWindows10 🤷‍♂️

ricmestre commented 1 year ago

Right, I just tested and IntuneDeviceConfigurationEndpointProtectionPolicyWindows10 is actually working and setting up Assignments property, but then again that one suffers from other problems which makes it not be in desired state as well...

William-Francillette commented 1 year ago

The Id issue was merged in Dev today

ricmestre commented 1 year ago

Yep, I know I tested the affected version without your change but in verbose mode the target values looked oddly suspicious along with the Id problem.

I'll confirm if it still has any issues or not when I get back home, nevertheless if it has I'll raise a separate issue for that one, otherwise if it works I'll just let you know here.

William-Francillette commented 1 year ago

🤔 Assignments have changed in the API - the action assign doesn't exist anymore so have to rethink how to manage those

ricmestre commented 1 year ago

Oh the perks of using beta APIs, I feel your pain!

William-Francillette commented 1 year ago

https://learn.microsoft.com/en-us/graph/api/intune-shared-windowsautopilotdeploymentprofile-assign?view=graph-rest-beta

Ouch the API doc is not up to date

William-Francillette commented 1 year ago

Hi @peombwa, hope you're keeping well

1- This doc (sdk) is missing the parameter WindowsAutopilotDeploymentProfileAssignmentId

2- Using Get-MgBetaDeviceManagementWindowsAutopilotDeploymentProfileAssignment, is there a way to retrieve the groupId of the assignment other than parsing the assignment id?

3- It seems like there was a change in the API in regards of Assignments for some Intune policies like this one DeviceManagementWindowsAutopilotDeploymentProfile: the assign action was replaced by assignments Would you have a list of those policies using this new action or would that be present in the schema?

4- There is some discrepancies now between the published documentation and the API such as this doc https://learn.microsoft.com/en-us/graph/api/intune-shared-windowsautopilotdeploymentprofile-assign?view=graph-rest-beta Not sure where to report this, the last time I tried to contact the API teams from my tenant (support ticket) I was not able to get through and the ticket was just got lost in translation ...

ricmestre commented 1 year ago

@william-francillette Just to confirm that IntuneDeviceConfigurationEndpointProtectionPolicyWindows10 is working perfectly now, on the other hand I found yet another problem with IntuneRoleDefinition 😭

ricmestre commented 1 year ago

By the way I'm testing and finding all this stuff with my own pipeline and throwing examples at it to make real deployments, but it would definitely be something that would help the project having it automated directly here in this repo instead every time a new resource is added. See discussion https://github.com/microsoft/Microsoft365DSC/issues/3458 about this with @andikrueger

ricmestre commented 1 year ago

IntuneDeviceEnrollmentStatusPageWindows10 is also affected but additionally also prints out problems with every property inside the assignments, this is just an example below but removing the affected property then complains about the next one.

Item has already been added. Key in dictionary: 'dataType'  Key being added: 'dataType'
William-Francillette commented 1 year ago

Quick update: I have a replacement solution for IntuneWindowsAutopilotDeploymentProfileAzureADJoined and tested successfully I'll be updating IntuneWindowsAutopilotDeploymentProfileAzureADHybridJoined and IntuneWindowsUpdateForBusinessRingUpdateProfileWindows10 tonight and post the PR if it all goes to plan

ricmestre commented 1 year ago

@william-francillette Great! Are you using their new API? Did you find documentation for it?

What about these 2 below? At least IntuneDeviceConfigurationPolicyWindows10 knocks several policies that I cannot use because of this issue.

IntuneDeviceConfigurationPolicyWindows10 IntuneDeviceEnrollmentStatusPageWindows10

William-Francillette commented 1 year ago

I went back using the sdk, this makes assignment management more tedious but no real choice and we need a stable solution Could you raise a different issue for those 2 please? So that I can post this PR quicker and resolve other issues as they come IntuneDeviceConfigurationPolicyWindows10 IntuneDeviceEnrollmentStatusPageWindows10

btw this policy (autopilot) is very restrictive compared to other in Intune, for example you can't delete a policy if it's assigned, or can't exclude collection if AllDevices is part of the included assignments. The API error messages are very generic and don't give you any information Another example, a create/update query will fail if the display name contains an hyphen with only a bad request response - it was painful debugging those I haven't managed all those cases because it's not really manageable without documentation - not sure what we can do for that and if it's really our scope to cover all APIs cases... @andikrueger ? @NikCharlebois ?

andikrueger commented 1 year ago

Maybe this is a bit of help: https://learn.microsoft.com/en-us/troubleshoot/mem/intune/device-enrollment/troubleshoot-windows-enrollment-errors#an-error-occurred-while-creating-autopilot-profile

Create a unique name for your devices. Names must be 15 characters or less, and can contain letters (a-z, A-Z), numbers (0-9), and hyphens (‐). Names can't be all numbers. Names can't contain blank space. Use the %SERIAL% macro to add a hardware-specific serial number. Or, use the %RAND:<# of digits>% macro to add a random string of numbers, the string contains <# of digits> digits. For example, MYPC-%RAND:6% generates a name such as MYPC-123456.

Are there any error codes within the API responses or really nothing at all - which would be really bad practice.

From a M365DSC standpoint, we should try to support all scenarios: CRUD. If delete or create a not an option for certain scenarios, it would be best practice to handle these cases (if this is possible). Otherwise we should look into a good documentation for this resource which would outline common mistakes.

William-Francillette commented 1 year ago

The errors are not evident at all .... the below error was due to an hyphen in the displayname image I don't know if the validations are publicly available in the schema ?

andikrueger commented 1 year ago

Any chance to expand the category information?

William-Francillette commented 1 year ago

will check in the evening

andikrueger commented 1 year ago

Looks like this request is related to this issue: https://github.com/Azure/autorest.powershell/issues/888

William-Francillette commented 1 year ago

Any chance to expand the category information?

Nothing of interest unfortunately image

ricmestre commented 1 year ago

Unfortunately this is true to other resources which also suffer from the "same problem", from the ones I mention in https://github.com/microsoft/Microsoft365DSC/issues/3458 that don't have an issue yet raised many of them also output the same error message but clearly the problem at hand it's actually something else not related to each other.

Graph really should return a proper error message when things go south.

William-Francillette commented 1 year ago

@ricmestre, could you check this sdk command please for me on your tenant Get-MgBetaDeviceManagementDeviceEnrollmentConfigurationAssignment -DeviceEnrollmentConfigurationId

It looks broken - I'm receiving a 400 error - is it same for you?

William-Francillette commented 1 year ago

Quick update:

I have a solution I'm happy with and updated

@ykuijs The solution incorporate the groupDisplayName as well so it should be fairly easy to push that to the rest of the resources Moving away from the API call as well and only using the sdk

I've got confused and mixed the resources so missed IntuneWindowsUpdateForBusinessRingUpdateProfileWindows10 Will check that one tonight and hopefully push the PR 😁

ricmestre commented 1 year ago

@William-Francillette Hi, just tested it and for me it's actually working.

Get-MgBetaDeviceManagementDeviceEnrollmentConfigurationAssignment -DeviceEnrollmentConfigurationId 20e486c4-c6e2-4594-a875-73953e64c4dd_DefaultLimit

Id                   : 20e486c4-c6e2-4594-a875-73953e64c4dd_DefaultLimit
Source               : direct
SourceId             :
Target               : Microsoft.Graph.Beta.PowerShell.Models.MicrosoftGraphDeviceAndAppManagementAssignmentTarget
AdditionalProperties : {}
William-Francillette commented 1 year ago

@William-Francillette Hi, just tested it and for me it's actually working.

Get-MgBetaDeviceManagementDeviceEnrollmentConfigurationAssignment -DeviceEnrollmentConfigurationId 20e486c4-c6e2-4594-a875-73953e64c4dd_DefaultLimit

Id                   : 20e486c4-c6e2-4594-a875-73953e64c4dd_DefaultLimit
Source               : direct
SourceId             :
Target               : Microsoft.Graph.Beta.PowerShell.Models.MicrosoftGraphDeviceAndAppManagementAssignmentTarget
AdditionalProperties : {}

Can you try with an ESP policy? the policy id should end with _Windows10EnrollmentCompletionPageConfiguration

ricmestre commented 1 year ago

yes, still works. you just need to Id.Split('_')[1] and call Get-MgGroup on it to get the group's display name if that's what you're looking for.

Id                   : c58e1b4c-1806-42b3-b16d-c10006562aae_b0b8fd3f-af2a-453b-be57-80182d599f02_c58e1b4c-1806-42b3-b16d-c10006562aae
Source               : direct
SourceId             : c58e1b4c-1806-42b3-b16d-c10006562aae
Target               : Microsoft.Graph.Beta.PowerShell.Models.MicrosoftGraphDeviceAndAppManagementAssignmentTarget
AdditionalProperties : {}
William-Francillette commented 1 year ago

@William-Francillette Hi, just tested it and for me it's actually working.

Get-MgBetaDeviceManagementDeviceEnrollmentConfigurationAssignment -DeviceEnrollmentConfigurationId 20e486c4-c6e2-4594-a875-73953e64c4dd_DefaultLimit

Id                   : 20e486c4-c6e2-4594-a875-73953e64c4dd_DefaultLimit
Source               : direct
SourceId             :
Target               : Microsoft.Graph.Beta.PowerShell.Models.MicrosoftGraphDeviceAndAppManagementAssignmentTarget
AdditionalProperties : {}

Can you try with an ESP policy? the policy id should end with _Windows10EnrollmentCompletionPageConfiguration

just realised there was a typo in my extract and was missing a character in the policyId 🤦‍♂️ typical - my copy paste skills are very poor ...

William-Francillette commented 1 year ago

yes, still works. you just need to Id.Split('_')[1] and call Get-MgGroup on it to get the group's display name if that's what you're looking for.

Id                   : c58e1b4c-1806-42b3-b16d-c10006562aae_b0b8fd3f-af2a-453b-be57-80182d599f02_c58e1b4c-1806-42b3-b16d-c10006562aae
Source               : direct
SourceId             : c58e1b4c-1806-42b3-b16d-c10006562aae
Target               : Microsoft.Graph.Beta.PowerShell.Models.MicrosoftGraphDeviceAndAppManagementAssignmentTarget
AdditionalProperties : {}

It's actually better than just splitting the id (I was initially doing that) - there's an issue with the display rendering of the object but the attribute are populated If you need to retrieve your group Id from the assignment you can use $assignment.Target.AdditionalProperties.groupId and also $assignment.Target.AdditionalProperties."@odata.type" Attributes in AdditionalProperties are case sensitive so make sure to spell them right

William-Francillette commented 1 year ago

@ricmestre can you try removing an assignment using Remove-MgBetaDeviceManagementDeviceEnrollmentConfigurationAssignment

I'm getting a 400 error from the sdk and Graph explorer - also the Intune Portal uses the action assign but the documentation shows using CRUD with assignments https://learn.microsoft.com/en-us/graph/api/intune-onboarding-enrollmentconfigurationassignment-delete?view=graph-rest-beta&tabs=http

Get and List work fine but Create and Delete fail

ricmestre commented 1 year ago

That generic error message from Graph we all love and hate! I'll try it out later on today and will provide you feedback.

Thank you a ton for taking care of this!

ricmestre commented 1 year ago

No dice, I'm also getting error 400.

Remove-MgBetaDeviceManagementDeviceEnrollmentConfigurationAssignment : No OData route exists that match template ~/singleton/navigation/key/navigation/key with http verb DELETE for request /StatelessOnboardingS ervice/deviceManagement/deviceEnrollmentConfigurations('c58e1b4c-1806-42b3-b16d-c10006562aae_Windows10EnrollmentCompletionPageConfiguration')/assignments('c58e1b4c-1806-42b3-b16d-c10006562aae_b0b8fd3f-af2a-453b -be57-80182d599f02_c58e1b4c-1806-42b3-b16d-c10006562aae').

Status: 400 (BadRequest)
ErrorCode: No method match route template
Date: 2023-11-24T19:18:38
Headers:
Transfer-Encoding             : chunked
Vary                          : Accept-Encoding
Strict-Transport-Security     : max-age=31536000
request-id                    : 00659044-c7c2-452b-ac57-883145c12b19
client-request-id             : a9633001-bb9c-48d1-9d3e-6fde235a573a
x-ms-ags-diagnostic           : {"ServerInfo":{"DataCenter":"France
Central","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"PA2PEPF000150A6"}}
Date                          : Fri, 24 Nov 2023 19:18:37 GMT
At line:1 char:1
+ Remove-MgBetaDeviceManagementDeviceEnrollmentConfigurationAssignment  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: ({ DeviceEnrollm...e, IfMatch =  }:<>f__AnonymousType66`3) [Remove-MgBetaDe...signment_Delete], Exception                                                              + FullyQualifiedErrorId : No method match route template,Microsoft.Graph.Beta.PowerShell.Cmdlets.RemoveMgBetaDeviceManagementDeviceEnrollmentConfigurationAssignment_Delete
William-Francillette commented 1 year ago

Yep I think the API is broken as I get the same result in the Graph Explorer

Will continue this discussion in the other issue :D

William-Francillette commented 1 year ago

Good news PR posted and fixed IntuneDeviceEnrollmentStatusPageWindows10 by using the assign action from the API The sdk won't work for now until the API is using assignments CRUD instead of the assign action

ricmestre commented 1 year ago

Looks great to me :D

Additionally you're also removing the Id property from Test-TargetResource on IntuneWindowsAutopilotDeploymentProfileAzureAD{,Hybrid}Joined but that is to solve something else and I already have PR #3893 to solve that, in fact there's a few more resources I found so far that also require the same treatment.