Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assert-M365DSCBlueprint: Reports as drift if property name doesn't have the expected casing #2873

Closed
ricmestre opened this issue Feb 6, 2023 · 5 comments · Fixed by #2955 or #2986
Closed
Labels
Bug Something isn't working Core Engine

Comments

@ricmestre
Copy link
Contributor

Details of the scenario you tried and the problem that is occurring

If Blueprint contains properties that don't have the expected casing (mismatch between lower and upper cases) then Assert-M365DSCBlueprint will report them as drifts, even if properties were taken directly from their respective schemas with the casing intact. See Blueprint below some properties such as osMinimumVersion, passwordMinimumLength, etc and the expected casing in comment in the same line.

Verbose logs showing the problem

Performing an Assert-M365DSCBlueprint between the Blueprint below and my tenant reports the following drifts, even though the values are correct, just the casing is not the one expected. On IntuneDeviceCompliancePolicyAndroidDeviceOwner please disregard properties Assignments and Description.

[
    {
        "ResourceName":  "IntuneDeviceCompliancePolicyAndroidDeviceOwner",
        "Key":  "DisplayName",
        "KeyValue":  "Android Work Profile - Compliance - Standard",
        "Properties":  [
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "Assignments",
                               "ValueInSource":  [

                                                 ]
                           },
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "Description",
                               "ValueInSource":  ""
                           },
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "OsMinimumVersion",
                               "ValueInSource":  "8.0"
                           },
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "PasswordMinimumLength",
                               "ValueInSource":  "6"
                           },
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "PasswordRequired",
                               "ValueInSource":  true
                           },
                           {
                               "ValueInDestination":  "# PasswordMinimumLength",
                               "ParameterName":  "_metadata_passwordMinimumLength",
                               "ValueInSource":  null
                           },
                           {
                               "ValueInDestination":  "# PasswordRequired",
                               "ParameterName":  "_metadata_passwordRequired",
                               "ValueInSource":  null
                           },
                           {
                               "ValueInDestination":  "# OsMinimumVersion",
                               "ParameterName":  "_metadata_osMinimumVersion",
                               "ValueInSource":  null
                           }
                       ]
    },
    {
        "ResourceName":  "IntuneDeviceEnrollmentPlatformRestriction",
        "Key":  "DisplayName",
        "KeyValue":  "All users and all devices",
        "Properties":  [
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "IosOsMaximumVersion",
                               "ValueInSource":  ""
                           },
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "IosOsMinimumVersion",
                               "ValueInSource":  ""
                           },
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "IosPersonalDeviceEnrollmentBlocked",
                               "ValueInSource":  false
                           },
                           {
                               "ValueInDestination":  null,
                               "ParameterName":  "IosPlatformBlocked",
                               "ValueInSource":  false
                           },
                           {
                               "ValueInDestination":  "# IosOsMaximumVersion",
                               "ParameterName":  "_metadata_iOSOsMaximumVersion",
                               "ValueInSource":  null
                           },
                           {
                               "ValueInDestination":  "# IosOsMinimumVersion",
                               "ParameterName":  "_metadata_iOSOsMinimumVersion",
                               "ValueInSource":  null
                           },
                           {
                               "ValueInDestination":  "# IosPlatformBlocked",
                               "ParameterName":  "_metadata_iOSPlatformBlocked",
                               "ValueInSource":  null
                           },
                           {
                               "ValueInDestination":  "# IosPersonalDeviceEnrollmentBlocked",
                               "ParameterName":  "_metadata_iOSPersonalDeviceEnrollmentBlocked",
                               "ValueInSource":  null
                           }
                       ]
    }
]

Suggested solution to the issue

Match property names during Assert-M365DSCBlueprint without performing casing matching since property names are supposed to be unique already between each other.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

Configuration ConfigureMicrosoft365
{
    Param(
        [Parameter(Mandatory = $true)]
        [PSCredential]
        $Credscredential
    )

    Import-DscResource -ModuleName Microsoft365DSC

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

    Node localhost
    {
        IntuneDeviceCompliancePolicyAndroidDeviceOwner 6971e360-6852-42fd-ab1a-6404d171113e
        {
            AdvancedThreatProtectionRequiredSecurityLevel      = "unavailable";
            Credential                                         = $Credscredential;
            DeviceThreatProtectionEnabled                      = $False;
            DeviceThreatProtectionRequiredSecurityLevel        = "medium";
            DisplayName                                        = "Android Work Profile - Compliance - Standard";
            Ensure                                             = "Present";
            osMinimumVersion                                   = "8.0"; # OsMinimumVersion
            passwordMinimumLength                              = 6; # PasswordMinimumLength
            passwordRequired                                   = $True; # PasswordRequired
            PasswordRequiredType                               = "numeric";
            RoleScopeTagIds                                    = "0";
            SecurityRequireSafetyNetAttestationBasicIntegrity  = $True;
            SecurityRequireSafetyNetAttestationCertifiedDevice = $False;
            StorageRequireEncryption                           = $True;
        }
	IntuneDeviceEnrollmentPlatformRestriction e71d1a1a-c054-4837-bccd-6bfcc0bb54ab
        {
            AndroidOsMaximumVersion                      = "";
            AndroidOsMinimumVersion                      = "";
            AndroidPersonalDeviceEnrollmentBlocked       = $False;
            AndroidPlatformBlocked                       = $False;
            Credential                                   = $Credscredential;
            Description                                  = "This is the default Device Type Restriction applied with the lowest priority to all users regardless of group membership.";
            DisplayName                                  = "All users and all devices";
            Ensure                                       = "Present";
            iOSOsMaximumVersion                          = ""; # IosOsMaximumVersion
            iOSOsMinimumVersion                          = ""; # IosOsMinimumVersion
            iOSPersonalDeviceEnrollmentBlocked           = $False; # IosPersonalDeviceEnrollmentBlocked
            iOSPlatformBlocked                           = $False; # IosPlatformBlocked
            MacPersonalDeviceEnrollmentBlocked           = $False;
            MacPlatformBlocked                           = $False;
            WindowsMobileOsMaximumVersion                = "";
            WindowsMobileOsMinimumVersion                = "";
            WindowsMobilePersonalDeviceEnrollmentBlocked = $False;
            WindowsMobilePlatformBlocked                 = $True;
            WindowsOsMaximumVersion                      = "";
            WindowsOsMinimumVersion                      = "";
            WindowsPersonalDeviceEnrollmentBlocked       = $False;
            WindowsPlatformBlocked                       = $False;
        }
    }
}

The operating system the target node is running

OsName : Microsoft Windows 10 Enterprise
OsOperatingSystemSKU : EnterpriseEdition
OsArchitecture : 64-bit
WindowsVersion : 2009
WindowsBuildLabEx : 19041.1.amd64fre.vb_release.191206-1406
OsLanguage : en-US
OsMuiLanguages : {en-US, pt-PT}

Version of the DSC module that was used ('dev' if using current dev branch)

1.23.201.1

@ricmestre
Copy link
Contributor Author

Note that this only happens with Assert-M365DSCBlueprint, if I use the same Blueprint with Start-DscConfiguration against same target tenant then both policies report as already being correct (Test-TargetResource returned True) and no changes are performed.

VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'. VERBOSE: An LCM method call arrived from computer DC with user sid S-1-5-21-1684320223-1890830632-2920597831-500. VERBOSE: [DC]: LCM: [ Start Set ] VERBOSE: [DC]: LCM: [ Start Resource ] [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] VERBOSE: [DC]: LCM: [ Start Test ] [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] VERBOSE: [DC]: [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] Testing configuration of Intune Android Work Profile Device Compliance Policy {Android Work Profile - Compliance - Standard} VERBOSE: [DC]: [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] Checking for the Intune Android Work Profile Device Compliance Policy {Android Work Profile - Compliance - Standard} VERBOSE: [DC]: [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] Found Intune Android Device Owner Device Compliance Policy with displayName {Android Work Profile - Compliance - Standard} VERBOSE: [DC]: [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] Current Values: AdvancedThreatProtectionRequiredSecurityLevel=unavailable; ApplicationId=; ApplicationSecret=$null; Assignments=(); CertificateThumbprint=; Credential=; Description=; DeviceThreatProtectionEnabled=False; DeviceThreatProtectionRequiredSecurityLevel=medium; DisplayName=Android Work Profile - Compliance - Standard; Ensure=Present; Managedidentity=False; OsMaximumVersion=$null; OsMinimumVersion=8.0; PasswordExpirationDays=$null; PasswordMinimumLength=6; PasswordMinutesOfInactivityBeforeLock=$null; PasswordPreviousPasswordCountToBlock=$null; PasswordRequired=True; PasswordRequiredType=numeric; RoleScopeTagIds=(0); SecurityRequireIntuneAppIntegrity=$null; SecurityRequireSafetyNetAttestationBasicIntegrity=True; SecurityRequireSafetyNetAttestationCertifiedDevice=False; StorageRequireEncryption=True; TenantId=*** VERBOSE: [DC]: [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] Target Values: AdvancedThreatProtectionRequiredSecurityLevel=unavailable; Credential=; DeviceThreatProtectionEnabled=False; DeviceThreatProtectionRequiredSecurityLevel=medium; DisplayName=Android Work Profile - Compliance - Standard; Ensure=Present; OsMinimumVersion=8.0; PasswordMinimumLength=6; PasswordRequired=True; PasswordRequiredType=numeric; RoleScopeTagIds=(0); SecurityRequireSafetyNetAttestationBasicIntegrity=True; SecurityRequireSafetyNetAttestationCertifiedDevice=False; StorageRequireEncryption=True; Verbose=True VERBOSE: [DC]: [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] Test-TargetResource returned True VERBOSE: [DC]: LCM: [ End Test ] [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] in 18.0350 seconds. VERBOSE: [DC]: LCM: [ Skip Set ] [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] VERBOSE: [DC]: LCM: [ End Resource ] [[IntuneDeviceCompliancePolicyAndroidDeviceOwner]6971e360-6852-42fd-ab1a-6404d171113e] VERBOSE: [DC]: LCM: [ Start Resource ] [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] VERBOSE: [DC]: LCM: [ Start Test ] [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] VERBOSE: [DC]: [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] Testing configuration of Device Enrollment Platform Restriction {All users and all devices} VERBOSE: [DC]: [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] Checking for the Intune Device Enrollment Restriction {All users and all devices} VERBOSE: [DC]: [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] Found Device Enrollment Platform Restriction with Name {All users and all devices} VERBOSE: [DC]: [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] Current Values: AndroidOsMaximumVersion=; AndroidOsMinimumVersion=; AndroidPersonalDeviceEnrollmentBlocked=False; AndroidPlatformBlocked=False; ApplicationId=; ApplicationSecret=$null; CertificateThumbprint=; Credential=; Description=This is the default Device Type Restriction applied with the lowest priority to all users regardless of group membership.; DisplayName=All users and all devices; Ensure=Present; IosOsMaximumVersion=; IosOsMinimumVersion=; IosPersonalDeviceEnrollmentBlocked=False; IosPlatformBlocked=False; MacPersonalDeviceEnrollmentBlocked=False; MacPlatformBlocked=False; Managedidentity=False; TenantId=; WindowsMobileOsMaximumVersion=; WindowsMobileOsMinimumVersion=; WindowsMobilePersonalDeviceEnrollmentBlocked=False; WindowsMobilePlatformBlocked=True; WindowsOsMaximumVersion=; WindowsOsMinimumVersion=; WindowsPersonalDeviceEnrollmentBlocked=False; WindowsPlatformBlocked=False VERBOSE: [DC]: [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] Target Values: AndroidOSMaximumVersion=; AndroidOSMinimumVersion=; AndroidPersonalDeviceEnrollmentBlocked=False; AndroidPlatformBlocked=False; Credential=***; Description=This is the default Device Type Restriction applied with the lowest priority to all users regardless of group membership.; DisplayName=All users and all devices; Ensure=Present; iOSOSMaximumVersion=; iOSOSMinimumVersion=; iOSPersonalDeviceEnrollmentBlocked=False; iOSPlatformBlocked=False; MacPersonalDeviceEnrollmentBlocked=False; MacPlatformBlocked=False; Verbose=True; WindowsMobileOSMaximumVersion=; WindowsMobileOSMinimumVersion=; WindowsMobilePersonalDeviceEnrollmentBlocked=False; WindowsMobilePlatformBlocked=True; WindowsOSMaximumVersion=; WindowsOSMinimumVersion=; WindowsPersonalDeviceEnrollmentBlocked=False; WindowsPlatformBlocked=False VERBOSE: [DC]: [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] Test-TargetResource returned True VERBOSE: [DC]: LCM: [ End Test ] [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] in 4.4230 seconds. VERBOSE: [DC]: LCM: [ Skip Set ] [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] VERBOSE: [DC]: LCM: [ End Resource ] [[IntuneDeviceEnrollmentPlatformRestriction]e71d1a1a-c054-4837-bccd-6bfcc0bb54ab] VERBOSE: [DC]: LCM: [ End Set ] VERBOSE: [DC]: LCM: [ End Set ] in 26.4010 seconds. VERBOSE: Operation 'Invoke CimMethod' complete. VERBOSE: Time taken for configuration job to complete is 27.637 seconds

@NikCharlebois
Copy link
Collaborator

NikCharlebois commented Feb 7, 2023

I am not able to reproduce the issue. For example, the following resource is part of my blueprint:

        TeamsTenantNetworkSubnet 832ac104-2c7b-4441-92c2-03108d1211d7
        {
            Credential           = $Credscredential;
            Description          = "Nik Test";
            Ensure               = "Present";
            iDentity             = "192.168.0.0";
            maskbits             = 24;
            NetworkSiteID        = "nik";
        }

The export generates the following (notice the casing differences):

        TeamsTenantNetworkSubnet e3dd957a-04fb-4df4-aab4-2b758b88e970
        {
            Credential           = $Credscredential;
            Description          = "Nik Test";
            Ensure               = "Present";
            Identity             = "192.168.0.0";
            MaskBits             = 24;
            NetworkSiteID        = "Nik";
        }

@ricmestre
Copy link
Contributor Author

Maybe it's just with certain properties? As I mentioned the problem is not with exporting or applying the blueprint, it's only when using assert is called, or more specifically when it does the Delta I'm getting that JSON as result

@ricmestre
Copy link
Contributor Author

ricmestre commented Feb 22, 2023

Hi, just to let you know this is still happening with 1.23.215.1, as I've mentioned the problem is not importing/exporting the blueprint since that is working without issues, the problem is actually when using Assert-M365DSCBlueprint between the blueprint and the tenant.

Using the assert it will report that parameters OsMinimumVersion/PasswordMinimumLength/PasswordRequired for resource IntuneDeviceCompliancePolicyAndroidDeviceOwner are not present in the blueprint and same for params IosOsMaximumVersion/IosOsMinimumVersion/IosPersonalDeviceEnrollmentBlocked/IosPlatformBlocked for resource IntuneDeviceEnrollmentPlatformRestriction.

There may be actually other resources with the same problem, but these are the ones I found so far that has impact on our side.

@andikrueger andikrueger added Bug Something isn't working and removed Pending Information labels Feb 22, 2023
@ricmestre
Copy link
Contributor Author

To note that the initial problem comes directly from the schemas of these 2 resources not having the correct casing for those parameters and therefore changing the MOFs would "fix" this for now but soon enough we will have more resources to compare and for sure will get the same problem again.

This boils down to the fact that function Compare-M365DSCConfigurations seems to be comparing casing where it shouldn't since parameters are supposed to be unique between each other as in you cannot have in the same resource a param called IosOsMaximumVersion and another iOSOsMaximumVersion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working Core Engine
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants