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

IntuneAppProtectionPolicyIOS - Test-TargetResource returns false even if config matches existing policy #2942

Closed
menswearUK opened this issue Feb 27, 2023 · 15 comments · Fixed by #2988 or #3014

Comments

@menswearUK
Copy link
Contributor

The Test-TargetResource function in the IntuneAppProtectionPolicyIOS returns false even though it should return true.
This can be seen either through the verbose output of the start-DSCConfiguration command or in the output of Test-DSCConfiguration.
The Test will report a false match even using a config exported from the tenant immediately before running the configuration, so the exported document does not return a true value for the policy it was exported from

The cause seems to be that the command Get-MgDeviceAppManagementiOSManagedAppProtection in Get-TargetResource is running in the v1.0 profile rather than the beta profile as specified at the start of that function - this means the function returns null values for some settings which are correctly listed on the exported document.

Verbose logs showing the problem

I've pasted the current/expected config results and the false outcome - this is using a newly created test profile
VERBOSE: [COMPUTER]: [[IntuneAppProtectionPolicyiOS]12345678-1234-1234-1234-123456789123]
Current Values: AllowedDataStorageLocations=(); AllowedInboundDataTransferSources=allApps;
AllowedIosDeviceModels=$null; AllowedOutboundClipboardSharingExceptionLength=$null;
AllowedOutboundClipboardSharingLevel=managedAppsWithPasteIn; AllowedOutboundDataTransferDestinations=allApps;
AppActionIfDeviceComplianceRequired=; AppActionIfIosDeviceModelNotAllowed=; AppActionIfMaximumPinRetriesExceeded=;
AppDataEncryptionType=whenDeviceLocked; ApplicationId=; ApplicationSecret=;
Apps=(com.microsoft.bing.halseyassistant,com.microsoft.d365.fs.mobile,com.microsoft.dynamics,com.microsoft.dynamics.inv
oice,com.microsoft.dynamics.iphone.moca,com.microsoft.dynamics.iphone.moca.fieldservices,com.microsoft.dynamics.iphone.
moca.sales,com.microsoft.lync2013.iphone,com.microsoft.mobile.polymer,com.microsoft.msapps,com.microsoft.msedge,com.mic rosoft.o365shdmobileapp,com.microsoft.office.excel,com.microsoft.office.outlook,com.microsoft.office.powerpoint,com.mic rosoft.office.word,com.microsoft.office365booker,com.microsoft.officelens,com.microsoft.officemobile,com.microsoft.onen ote,com.microsoft.plannermobile,com.microsoft.powerbimobile,com.microsoft.procsimo,com.microsoft.ramobile,com.microsoft .rms-sharing,com.microsoft.scmx,com.microsoft.sharepoint,com.microsoft.shiftr,com.microsoft.skydrive,com.microsoft.skyp e.teams,com.microsoft.splists,com.microsoft.stream,com.microsoft.to-do,com.microsoft.visio,com.microsoft.whiteboard,com .microsoft.workfolders,com.veradocs.ios.appstore.intune,wefwef); Assignments=(); CertificateThumbprint=; ContactSyncBlocked=False; Credential=$null; CustomBrowserProtocol=; DataBackupBlocked=False; Description=some descriptive words to describe the policy in the description. indescribable; DeviceComplianceRequired=True; DisableAppPinIfDevicePinIsSet=False; DisableProtectionOfManagedOutboundOpenInData=$null; DisplayName=testiospolicy; Ensure=Present; ExcludedGroups=(); ExemptedAppProtocols=(); FaceIdBlocked=False; FilterOpenInToOnlyManagedApps=$null; FingerprintBlocked=False; Identity=T_12345678-4321-4321-4321-123456789123; ManagedBrowser=notConfigured; ManagedBrowserToOpenLinksRequired=False; Managedidentity=False; MaximumPinRetries=5; MinimumPinLength=4; MinimumRequiredAppVersion=$null; MinimumRequiredOsVersion=$null; MinimumRequiredSdkVersion=$null; MinimumWarningAppVersion=$null; MinimumWarningOSVersion=$null; MinimumWipeAppVersion=$null; MinimumWipeOSVersion=$null; MinimumWipeSdkVersion=$null; NotificationRestriction=; OrganizationalCredentialsRequired=False; PeriodBeforePinReset=90.00:00:00; PeriodOfflineBeforeAccessCheck=12:00:00; PeriodOfflineBeforeWipeIsEnforced=90.00:00:00; PeriodOnlineBeforeAccessCheck=00:30:00; PinCharacterSet=numeric; PinRequired=True; PinRequiredInsteadOfBiometricTimeout=$null; PrintBlocked=False; ProtectInboundDataFromUnknownSources=$null; SaveAsBlocked=False; SimplePinBlocked=True; TargetedAppManagementLevels=; TenantId=***
VERBOSE: [COMPUTER]: [[IntuneAppProtectionPolicyiOS]12345678-1234-1234-1234-123456789123]
Target Values: AllowedDataStorageLocations=(); AllowedInboundDataTransferSources=allApps; AllowedOutboundClipboardSharingExceptionLength=0; AllowedOutboundClipboardSharingLevel=managedAppsWithPasteIn; AllowedOutboundDataTransferDestinations=allApps; AppActionIfDeviceComplianceRequired=block; AppActionIfIosDeviceModelNotAllowed=block; AppActionIfMaximumPinRetriesExceeded=block; AppDataEncryptionType=whenDeviceLocked; ApplicationId=; ApplicationSecret=; Apps=(com.microsoft.bing.halseyassistant,com.microsoft.d365.fs.mobile,com.microsoft.dynamics,com.microsoft.dynamics.inv oice,com.microsoft.dynamics.iphone.moca,com.microsoft.dynamics.iphone.moca.fieldservices,com.microsoft.dynamics.iphone. moca.sales,com.microsoft.lync2013.iphone,com.microsoft.mobile.polymer,com.microsoft.msapps,com.microsoft.msedge,com.mic rosoft.o365shdmobileapp,com.microsoft.office.excel,com.microsoft.office.outlook,com.microsoft.office.powerpoint,com.mic rosoft.office.word,com.microsoft.office365booker,com.microsoft.officelens,com.microsoft.officemobile,com.microsoft.onen ote,com.microsoft.plannermobile,com.microsoft.powerbimobile,com.microsoft.procsimo,com.microsoft.ramobile,com.microsoft .rms-sharing,com.microsoft.scmx,com.microsoft.sharepoint,com.microsoft.shiftr,com.microsoft.skydrive,com.microsoft.skyp e.teams,com.microsoft.splists,com.microsoft.stream,com.microsoft.to-do,com.microsoft.visio,com.microsoft.whiteboard,com .microsoft.workfolders,com.veradocs.ios.appstore.intune,wefwef); Assignments=(); ContactSyncBlocked=False; CustomBrowserProtocol=; DataBackupBlocked=False; Description=some descriptive words to describe the policy in the description. indescribable; DeviceComplianceRequired=True; DisableAppPinIfDevicePinIsSet=False; DisableProtectionOfManagedOutboundOpenInData=False; DisplayName=testiospolicy; Ensure=Present; ExcludedGroups=(); ExemptedAppProtocols=(Default:skype;app-settings;calshow;itms;itmss;itms-apps;itms-appss;itms-services;); FaceIdBlocked=False; FilterOpenInToOnlyManagedApps=False; FingerprintBlocked=False; Identity=T_12345678-4321-4321-4321-123456789123; ManagedBrowser=notConfigured; ManagedBrowserToOpenLinksRequired=False; ManagedIdentity=False; MaximumPinRetries=5; MinimumPinLength=4; NotificationRestriction=allow; OrganizationalCredentialsRequired=False; PeriodBeforePinReset=90.00:00:00; PeriodOfflineBeforeAccessCheck=12:00:00; PeriodOfflineBeforeWipeIsEnforced=90.00:00:00; PeriodOnlineBeforeAccessCheck=00:30:00; PinCharacterSet=numeric; PinRequired=True; PinRequiredInsteadOfBiometricTimeout=00:30:00; PrintBlocked=False;
ProtectInboundDataFromUnknownSources=False; SaveAsBlocked=False; SimplePinBlocked=True;
TargetedAppManagementLevels=unmanaged; TenantId=***; Verbose=True
VERBOSE: [COMPUTER]: [[IntuneAppProtectionPolicyiOS]12345678-1234-1234-1234-123456789123]
Test-TargetResource returned False

Suggested solution to the issue

Adding the New-M365DSCConnection command to the start of the Test-TargetResource function appears to resolve this error and return the objects using the beta graph profile. it's not clear to me why this should be but testing does show it to produce the correct results

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

        IntuneAppProtectionPolicyiOS 12345678-1234-1234-1234-123456789123
        {
            AllowedDataStorageLocations                    = @();
            AllowedInboundDataTransferSources              = "allApps";
            AllowedOutboundClipboardSharingExceptionLength = 0;
            AllowedOutboundClipboardSharingLevel           = "managedAppsWithPasteIn";
            AllowedOutboundDataTransferDestinations        = "allApps";
            AppActionIfDeviceComplianceRequired            = "block";
            AppActionIfIosDeviceModelNotAllowed            = "block";
            AppActionIfMaximumPinRetriesExceeded           = "block";
            AppDataEncryptionType                          = "whenDeviceLocked";
            ApplicationId                                  = $ConfigurationData.NonNodeData.ApplicationId;
            ApplicationSecret                              = New-Object System.Management.Automation.PSCredential ('ApplicationSecret', (ConvertTo-SecureString $ConfigurationData.NonNodeData.ApplicationSecret -AsPlainText -Force));
            Apps                                           = @("com.microsoft.bing.halseyassistant","com.microsoft.d365.fs.mobile","com.microsoft.dynamics","com.microsoft.dynamics.invoice","com.microsoft.dynamics.iphone.moca","com.microsoft.dynamics.iphone.moca.fieldservices","com.microsoft.dynamics.iphone.moca.sales","com.microsoft.lync2013.iphone","com.microsoft.mobile.polymer","com.microsoft.msapps","com.microsoft.msedge","com.microsoft.o365shdmobileapp","com.microsoft.office.excel","com.microsoft.office.outlook","com.microsoft.office.powerpoint","com.microsoft.office.word","com.microsoft.office365booker","com.microsoft.officelens","com.microsoft.officemobile","com.microsoft.onenote","com.microsoft.plannermobile","com.microsoft.powerbimobile","com.microsoft.procsimo","com.microsoft.ramobile","com.microsoft.rms-sharing","com.microsoft.scmx","com.microsoft.sharepoint","com.microsoft.shiftr","com.microsoft.skydrive","com.microsoft.skype.teams","com.microsoft.splists","com.microsoft.stream","com.microsoft.to-do","com.microsoft.visio","com.microsoft.whiteboard","com.microsoft.workfolders","com.veradocs.ios.appstore.intune","wefwef");
            Assignments                                    = @();
            ContactSyncBlocked                             = $False;
            CustomBrowserProtocol                          = "";
            DataBackupBlocked                              = $False;
            Description                                    = "some descriptive words to describe the policy in the description. indescribable";
            DeviceComplianceRequired                       = $True;
            DisableAppPinIfDevicePinIsSet                  = $False;
            DisableProtectionOfManagedOutboundOpenInData   = $False;
            DisplayName                                    = "testiospolicy";
            Ensure                                         = "Present";
            ExcludedGroups                                 = @();
            ExemptedAppProtocols                           = @("Default:skype;app-settings;calshow;itms;itmss;itms-apps;itms-appss;itms-services;");
            FaceIdBlocked                                  = $False;
            FilterOpenInToOnlyManagedApps                  = $False;
            FingerprintBlocked                             = $False;
            Identity                                       = "T_12345678-4321-4321-4321-123456789123";
            ManagedBrowser                                 = "notConfigured";
            ManagedBrowserToOpenLinksRequired              = $False;
            Managedidentity                                = $False;
            MaximumPinRetries                              = 5;
            MinimumPinLength                               = 4;
            NotificationRestriction                        = "allow";
            OrganizationalCredentialsRequired              = $False;
            PeriodBeforePinReset                           = "90.00:00:00";
            PeriodOfflineBeforeAccessCheck                 = "12:00:00";
            PeriodOfflineBeforeWipeIsEnforced              = "90.00:00:00";
            PeriodOnlineBeforeAccessCheck                  = "00:30:00";
            PinCharacterSet                                = "numeric";
            PinRequired                                    = $True;
            PinRequiredInsteadOfBiometricTimeout           = "00:30:00";
            PrintBlocked                                   = $False;
            ProtectInboundDataFromUnknownSources           = $False;
            SaveAsBlocked                                  = $False;
            SimplePinBlocked                               = $True;
            TargetedAppManagementLevels                    = "unmanaged";
            TenantId                                       = $ConfigurationData.NonNodeData.TenantId;
        }

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

dev

@ykuijs
Copy link
Member

ykuijs commented Feb 28, 2023

@William-Francillette Any clue why the New-M365DSCConnection as the beginning of the Get method doesn't work properly?

@William-Francillette
Copy link
Contributor

That's an issue I've noticed and raised #2869
The profile is lost during test-targetresource but working fine in get-target resource
The quick fix is to add a select-mgprofile after new-m365dscconnection and force the beta api
The proper fix, I'm not sure 😕 may be a cached/global parameter

@menswearUK
Copy link
Contributor Author

@ykuijs I'm afraid I'm not sure why it behaves like this. The command in get-targetresource appears to be correct and does seem to work when called from elsewhere.

@William-Francillette - Thanks for this info. Sorry I didn't spot the issue you'd raised before raising this one.
Is Select-MgProfile the accepted workaround for the moment? I ask as you mentioned in your initial comments that it might not be a suitable solution.

I'll have a look and see if I get anywhere looking for cached/global params.

@powershellpr0mpt
Copy link
Contributor

By the looks of it this affects most [if not all] Intune policies.
Was playing with IntuneDeviceCompliancePolicyWindows10 for example and was running into quite a lot of values not being properly detected there:
image

But also when looking at various other policies, I notice a large discrepency between the v1.0 and beta results, causing DSC to think resources aren't in their desired state [even immediately after having just created the actual resource].

I'll give the quick fix as suggested by @William-Francillette a shot, if that works as intended I'll raise a PR for the resources where I know this causes issues!

@ykuijs
Copy link
Member

ykuijs commented Feb 28, 2023

@powershellpr0mpt That would be excellent!

FYI: This is a known issue with the Graph v1. The Graph v2 is on the verge of being release and will fix this issue. We are already working on moving all resources to this new version and just have to wait on the formal release. In the meantime we can use the workaround mentioned by @William-Francillette

@menswearUK
Copy link
Contributor Author

@ykuijs I've tried using select-mgprofile -beta as an option. It does lead to the correct results but it also results in a huge amount of extra verbose output. piping to out-null doesn't seem to be clearing this either.

I've been looking at this this afternoon and the problem seems to be that the beta profile doesn't get set the first time New-M365DSCConnection is run (which explains why my proposed fix worked, it ensured the connection had been run twice by the time we needed the beta profile).
After that it works fine and switches between 1.0 and beta with no issues. The problem seems to stem from the connect-m365Tenant command in MSCloudLoginAssistant module.

Might altering the New-M365DSCConnection function to check the configuration once set and correct it immediately be an alternative to amending multiple configurations? I've tested this myself and using select-mgprofile here does work - it also avoids the excessive verbose output seen when using it in the configuration functions

@powershellpr0mpt
Copy link
Contributor

n function to check the configuration once set and correct it immediately be an alternative to amending multiple configurations? I've tested this myself and using select-mgprofile here does work

I've also tried this on all the other Intune related cmdlets.
The biggest problem with using Select-MgProfile instead of using New-M365DscConnection is that Select-MgProfile will try and remove and re-import the entire Microsoft.Graph.Authentication module, causing the immense flooding of Verbose output that @menswearUK was mentioning (which I also encountered)

image

@ykuijs : I see that you've put the New-M365DscConnection solution as used in #2944 On-Hold, due to it being a workaround, but yesterday you seemed eager for me to implement the Select-MgProfile.

Both are a workaround, but the New-M365DscConnection solution seems to be the cleaner of the 2.
Do you want me to create PR's for all resources that are currently "Broken" or prefer to get to the bottom of this first?
Currently a lot of resources are not working as intended.

@menswearUK
Copy link
Contributor Author

@powershellpr0mpt @ykuijs - I'd be happier using New-M365DscConnection if we're fixing this at the configuration level due to the output. It's already the way the android version of this configuration gets around it.

Alternatively there's also the option of amending New-M365DSCConnection itself in M365DSCUtil.ps1, thus ensuring the command works as expected.
I'm aware there is some reluctance to make these changes due to the imminent update to use graph 2.0 but if we're talking about potentially updating all the intune configurations (probably others, too) wouldn't a few changes to one function be easier to manage than amending every configuration using a beta profile?
I've tested using select-mgprofile within New-M365DSCConnection itself and it does work as required (and without the excessive verbose output) - a quick check to see if the initial Connect-M365Tenant command had worked as intended and a correction if required would avoid running it when unnecessary too

@powershellpr0mpt
Copy link
Contributor

@menswearUK - I'm actually looking at this bit myself as well, I think it might be a scoping issue causing the problem, but am looking at if I can reproduce this as I type.

I agree that fixing the issue in New-M365DscConnection in M365DSCUtil.ps1 would be the preferred way from my perspective, but I've only been playing around with this a few weeks, so perhaps more experienced members/contributors can weigh in as well cough @ykuijs cough 😉 .

I'm personally a bit reluctant on "waiting for Graph SDK v2.0", because noone knows when it will actually be GA and the fix/workaround for these items is real simple and allows me to continue developing.

@menswearUK
Copy link
Contributor Author

@powershellpr0mpt - I'm with you on not waiting for the SDK updates - As you say, this is a simple fix (whichever way we implement it) and will fix quite a number of errors.

For what it's worth - the code I've added to new-M365DSCConnection is simply:

            ~Connect-M365Tenant command~

            #2942 - check correct profile applied
            if ($ProfileName -ne $global:MSCloudLoginConnectionProfile.MicrosoftGraph.ProfileName)
            {
                select-mgprofile -Name $profilename
            }

see, it only runs if it is required and just forces the profile to match what has been asked for.

I've only added it for my authentication method so far but if it is acceptable I can easily go through the function, drop it in the correct places, then update it to my existing PR.

I've steered clear of amending anything outside of individual configurations in the past as I'm aware of the wider implications but if we're looking for a proper fix then, unless we go to the cloud assistant module itself, I think this is the best place for it.

@powershellpr0mpt
Copy link
Contributor

@menswearUK - can you let me know where you've added that code exactly?
Then I can at least do that for my local environment in the meantime, without having to change every resource.

@ykuijs
Copy link
Member

ykuijs commented Mar 3, 2023

Hi guys, sorry for the little delay. Had a day off yesterday.

PR #2944 implements a single call to New-M365DSCConnection in the Test method. Even though that works, it is still an additional call on a place where it isn't needed. That is why I put that On-Hold.

I rather implement the solution @menswearUK suggests above. Could you guys test what happens with the Verbose output if you add this:

~Connect-M365Tenant command~

#2942 - check correct profile applied
if ($ProfileName -ne $global:MSCloudLoginConnectionProfile.MicrosoftGraph.ProfileName)
{
    $currVerbosePreference = $VerbosePreference
    $VerbosePreference = 'SilentlyContinue'
    select-mgprofile -Name $ProfileName
    $VerbosePreference = $currVerbosePreference
}

The Connect-M365Tenant is called on multiple places in the M365DSCUtil file. We have to add this code after each of these calls.

@powershellpr0mpt
Copy link
Contributor

powershellpr0mpt commented Mar 3, 2023

@ykuijs - Added this just now and verbose looks clean and normal 👍
Also, don't appologize for taking a day off 😄 , we're just impatient

powershellpr0mpt pushed a commit to powershellpr0mpt/Microsoft365DSC that referenced this issue Mar 3, 2023
@menswearUK
Copy link
Contributor Author

@ykuijs @powershellpr0mpt I don't actually think changing the verbose preference is required when it runs the command within New-M365DSCConnection - the lines I added didn't change any verbose settings but the output was fine

@menswearUK
Copy link
Contributor Author

I'll push my updates to the on-hold request so you can see where I added the lines - I also added a check that it was a msgraph connection call into the if statement

@ykuijs ykuijs linked a pull request Mar 3, 2023 that will close this issue
menswearUK added a commit to menswearUK/Microsoft365DSC that referenced this issue Mar 9, 2023
original PR failed when I tried to resolve conflicts, merged nothing - this contains the changes present in that PR
ykuijs added a commit that referenced this issue Mar 10, 2023
Update MSFT_IntuneAppProtectionPolicyiOS.psm1 - fixes #2942
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment