almenscorner/IntuneCD

[BUG] TypeError: NoneType is not iterable

Closed this issue · 11 comments

When running a backup of the intune configuration, we receive a TypeError: NoneType is not iterable

Screenshots
image

Run type (please complete the following information):
Azure Devops Pipeline

Additional context

Starting: IntuneCD backup

Task : Bash
Description : Run a Bash script on macOS, Linux, or Windows
Version : 3.231.5
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/bash

Generating script.
========================== Starting Command Output ===========================
/usr/bin/bash /home/vsts/work/_temp/5edf2cfa-1763-4171-a40f-4054624eab9b.sh
Backing up App Configuration: NSCT - Defender Endpoint Supervised Policy
Traceback (most recent call last):
File "/home/vsts/.local/bin/IntuneCD-startbackup", line 8, in
sys.exit(start())
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/run_backup.py", line 271, in start
run_backup(
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/run_backup.py", line 218, in run_backup
backup_intune(results, path, output, exclude, token, prefix, append_id, args)
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/backup_intune.py", line 14, in backup_intune
results.append(savebackup(path, output, exclude, token, prefix, append_id))
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/backup/Intune/backup_AppProtection.py", line 49, in savebackup
assignments = get_object_assignment(profile["id"], assignment_responses)
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/intunecdlib/graph_batch.py", line 284, in get_object_assignment
assignments_list = [
TypeError: 'NoneType' object is not iterable

##[error]Bash exited with code '1'.
##[error]Bash wrote one or more lines to the standard error stream.
##[error]Traceback (most recent call last):
File "/home/vsts/.local/bin/IntuneCD-startbackup", line 8, in

##[error] sys.exit(start())
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/run_backup.py", line 271, in start
run_backup(
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/run_backup.py", line 218, in run_backup
backup_intune(results, path, output, exclude, token, prefix, append_id, args)
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/backup_intune.py", line 14, in backup_intune
results.append(savebackup(path, output, exclude, token, prefix, append_id))
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/backup/Intune/backup_AppProtection.py", line 49, in savebackup
assignments = get_object_assignment(profile["id"], assignment_responses)
File "/home/vsts/.local/lib/python3.10/site-packages/IntuneCD/intunecdlib/graph_batch.py", line 284, in get_object_assignment
assignments_list = [
TypeError: 'NoneType' object is not iterable

Finishing: IntuneCD backup

Hi, can you verify that you do not have any App Protections that has an assignments towards a group that has been removed?

If i'm looking in the right place... I don't think we've ever used this bit (I'm assuming what's on screen is something Microsoft added by default):

image

image

image

I don't think MS has added any App Protection policy by default, at least I do not have one like that in my env. If you are not using it, can you remove it and try a new backup?

@almenscorner I've not done anything yet, as I wanted to understand where this policy has come from - I think I've now worked it out:

https://learn.microsoft.com/en-us/mem/intune/apps/app-protection-policy

There is a section "App protection global policy":

If a OneDrive administrator browses to admin.onedrive.com and selects Device access, they can set Mobile application management controls to the OneDrive and SharePoint client apps.

The settings, made available to the OneDrive Admin console, configure a special Intune app protection policy called the Global policy. This global policy applies to all users in your tenant, and has no way to control the policy targeting.

Once enabled, the OneDrive and SharePoint apps for iOS/iPadOS and Android are protected with the selected settings by default. An IT Pro can edit this policy in the [Microsoft Intune admin center](https://go.microsoft.com/fwlink/?linkid=2109431) to add more targeted apps and to modify any policy setting.

By default, there can only be one Global policy per tenant. However, you can use [Intune Graph APIs](https://learn.microsoft.com/en-us/mem/intune/developer/intune-graph-apis) to create extra global policies per tenant, but doing so isn't recommended. Creating extra global policies isn't recommended because troubleshooting the implementation of such a policy can become complicated.

While the Global policy applies to all users in your tenant, any standard Intune app protection policy will override these settings.

There is then a note: "The policy settings in the OneDrive Admin Center are no longer being updated. Microsoft Intune may be used instead".

So looking at that, I think we probably need to work out a code fix for this as presumably there will be other users that have a non-targetted policy here...

Okay so it is something that should be migrated to App Protection but there may be some legacy profiles created from the OD admin center..

What does this policy look like if you use Graph Explorer or similar to grab the json object? would be easier to implement a fix for that specific scenario if I know what the object looks like. You could also try a backup excluding assignments and see if you can export the object that way.

Assuming I've got the right endpoint - https://graph.microsoft.com/beta/deviceAppManagement/managedAppPolicies - that endpoint returns:

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#deviceAppManagement/managedAppPolicies",
    "@microsoft.graph.tips": "Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET deviceAppManagement/managedAppPolicies?$select=createdDateTime,description",
    "value": [
        {
            "@odata.type": "#microsoft.graph.defaultManagedAppProtection",
            "displayName": "OneDrive mobile policy",
            "description": "OneDrive mobile policy UX set via Admin UX",
            "createdDateTime": "2020-03-03T12:29:46.8114516Z",
            "lastModifiedDateTime": "2022-01-10T20:58:40Z",
            "roleScopeTagIds": [
                "0"
            ],
            "id": "G_f19e31ae-96d2-4c05-bb9f-b5dfca1fe9ec",
            "version": "\"0201d7ac-0000-0c00-0000-61dc9e000000\"",
            "periodOfflineBeforeAccessCheck": "PT1H30M",
            "periodOnlineBeforeAccessCheck": "P7D",
            "allowedInboundDataTransferSources": "allApps",
            "allowedOutboundDataTransferDestinations": "allApps",
            "organizationalCredentialsRequired": true,
            "allowedOutboundClipboardSharingLevel": "allApps",
            "dataBackupBlocked": false,
            "deviceComplianceRequired": false,
            "managedBrowserToOpenLinksRequired": false,
            "saveAsBlocked": false,
            "periodOfflineBeforeWipeIsEnforced": "P60D",
            "pinRequired": false,
            "maximumPinRetries": 5,
            "simplePinBlocked": false,
            "minimumPinLength": 8,
            "pinCharacterSet": "numeric",
            "periodBeforePinReset": "PT0S",
            "allowedDataStorageLocations": [],
            "contactSyncBlocked": false,
            "printBlocked": false,
            "fingerprintBlocked": false,
            "disableAppPinIfDevicePinIsSet": false,
            "maximumRequiredOsVersion": null,
            "maximumWarningOsVersion": null,
            "maximumWipeOsVersion": null,
            "minimumRequiredOsVersion": null,
            "minimumWarningOsVersion": null,
            "minimumRequiredAppVersion": null,
            "minimumWarningAppVersion": null,
            "minimumWipeOsVersion": null,
            "minimumWipeAppVersion": null,
            "appActionIfDeviceComplianceRequired": "block",
            "appActionIfMaximumPinRetriesExceeded": "block",
            "pinRequiredInsteadOfBiometricTimeout": null,
            "allowedOutboundClipboardSharingExceptionLength": 0,
            "notificationRestriction": "allow",
            "previousPinBlockCount": 0,
            "managedBrowser": "notConfigured",
            "maximumAllowedDeviceThreatLevel": "notConfigured",
            "mobileThreatDefenseRemediationAction": "block",
            "mobileThreatDefensePartnerPriority": null,
            "blockDataIngestionIntoOrganizationDocuments": false,
            "allowedDataIngestionLocations": [],
            "appActionIfUnableToAuthenticateUser": null,
            "dialerRestrictionLevel": "allApps",
            "gracePeriodToBlockAppsDuringOffClockHours": null,
            "protectedMessagingRedirectAppType": "anyApp",
            "appDataEncryptionType": "useDeviceSettings",
            "screenCaptureBlocked": false,
            "encryptAppData": false,
            "disableAppEncryptionIfDeviceEncryptionIsEnabled": false,
            "minimumRequiredSdkVersion": null,
            "deployedAppCount": 0,
            "minimumRequiredPatchVersion": "0000-00-00",
            "minimumWarningPatchVersion": "0000-00-00",
            "faceIdBlocked": false,
            "minimumWipeSdkVersion": null,
            "minimumWipePatchVersion": "0000-00-00",
            "allowedIosDeviceModels": null,
            "appActionIfIosDeviceModelNotAllowed": "block",
            "allowedAndroidDeviceManufacturers": null,
            "appActionIfAndroidDeviceManufacturerNotAllowed": "block",
            "thirdPartyKeyboardsBlocked": false,
            "filterOpenInToOnlyManagedApps": false,
            "disableProtectionOfManagedOutboundOpenInData": false,
            "protectInboundDataFromUnknownSources": false,
            "requiredAndroidSafetyNetDeviceAttestationType": "none",
            "appActionIfAndroidSafetyNetDeviceAttestationFailed": "block",
            "requiredAndroidSafetyNetAppsVerificationType": "none",
            "appActionIfAndroidSafetyNetAppsVerificationFailed": "block",
            "customBrowserProtocol": null,
            "customBrowserPackageId": null,
            "customBrowserDisplayName": null,
            "minimumRequiredCompanyPortalVersion": null,
            "minimumWarningCompanyPortalVersion": null,
            "minimumWipeCompanyPortalVersion": null,
            "allowedAndroidDeviceModels": [],
            "appActionIfAndroidDeviceModelNotAllowed": "block",
            "customDialerAppProtocol": null,
            "customDialerAppPackageId": null,
            "customDialerAppDisplayName": null,
            "biometricAuthenticationBlocked": false,
            "requiredAndroidSafetyNetEvaluationType": "basic",
            "blockAfterCompanyPortalUpdateDeferralInDays": 0,
            "warnAfterCompanyPortalUpdateDeferralInDays": 0,
            "wipeAfterCompanyPortalUpdateDeferralInDays": 0,
            "deviceLockRequired": false,
            "appActionIfDeviceLockNotSet": "block",
            "connectToVpnOnLaunch": false,
            "appActionIfDevicePasscodeComplexityLessThanLow": null,
            "appActionIfAccountIsClockedOut": null,
            "appActionIfDevicePasscodeComplexityLessThanMedium": null,
            "appActionIfDevicePasscodeComplexityLessThanHigh": null,
            "requireClass3Biometrics": false,
            "requirePinAfterBiometricChange": false,
            "fingerprintAndBiometricEnabled": null,
            "minimumWarningSdkVersion": null,
            "messagingRedirectAppUrlScheme": null,
            "messagingRedirectAppDisplayName": null,
            "messagingRedirectAppPackageId": null,
            "customSettings": [],
            "exemptedAppProtocols": [
                {
                    "name": "Default",
                    "value": "tel;telprompt;skype;app-settings;calshow;itms;itmss;itms-apps;itms-appss;itms-services;"
                }
            ],
            "exemptedAppPackages": [
                {
                    "name": "Default",
                    "value": ""
                }
            ]
        }
    ]
}

Looking at that, we could always skip assignment if this is the odata type "@odata.type": "#microsoft.graph.defaultManagedAppProtection"

I'd say that would seem the most reasonable fix - Microsoft seem to suggest there will only ever be one of these policies - with the disclaimer that you could technically make your own

I've included that in 2.0.8 beta, install the beta and let me know if the backup now is successful pip install IntuneCD==2.0.8b1

updated our pipeline - seems to build again so this is fixed as of 2.0.8 and tissue can be closed :)

image

Cool, I'll merge the changes to main and close this issue! :)