>, settings_table?: array, warnings: array} */ public function normalize(?array $snapshot, string $policyType, ?string $platform = null): array { $snapshot = is_array($snapshot) ? $snapshot : []; $displayName = Arr::get($snapshot, 'displayName') ?? Arr::get($snapshot, 'name'); $description = Arr::get($snapshot, 'description'); $warnings = []; if ($policyType === 'enrollmentRestriction') { $warnings[] = 'Restore is preview-only for Enrollment Restrictions.'; } if ($policyType === 'deviceEnrollmentLimitConfiguration') { $warnings[] = 'Restore is preview-only for Enrollment Limits.'; } if ($policyType === 'deviceEnrollmentPlatformRestrictionsConfiguration') { $warnings[] = 'Restore is preview-only for Platform Restrictions.'; } if ($policyType === 'deviceEnrollmentNotificationConfiguration') { $warnings[] = 'Restore is preview-only for Enrollment Notifications.'; } $generalEntries = [ ['key' => 'Type', 'value' => $policyType], ]; if (is_string($displayName) && $displayName !== '') { $generalEntries[] = ['key' => 'Display name', 'value' => $displayName]; } if (is_string($description) && $description !== '') { $generalEntries[] = ['key' => 'Description', 'value' => $description]; } $odataType = Arr::get($snapshot, '@odata.type'); if (is_string($odataType) && $odataType !== '') { $generalEntries[] = ['key' => '@odata.type', 'value' => $odataType]; } $roleScopeTagIds = Arr::get($snapshot, 'roleScopeTagIds'); if (is_array($roleScopeTagIds) && $roleScopeTagIds !== []) { $generalEntries[] = ['key' => 'Scope tag IDs', 'value' => array_values($roleScopeTagIds)]; } $settings = [ [ 'type' => 'keyValue', 'title' => 'General', 'entries' => $generalEntries, ], ]; $typeBlock = match ($policyType) { 'windowsAutopilotDeploymentProfile' => $this->buildAutopilotBlock($snapshot), 'windowsEnrollmentStatusPage' => $this->buildEnrollmentStatusPageBlock($snapshot), 'enrollmentRestriction' => $this->buildEnrollmentRestrictionBlock($snapshot), 'deviceEnrollmentLimitConfiguration' => $this->buildEnrollmentLimitBlock($snapshot), 'deviceEnrollmentPlatformRestrictionsConfiguration' => $this->buildEnrollmentPlatformRestrictionsBlock($snapshot), 'deviceEnrollmentNotificationConfiguration' => $this->buildEnrollmentNotificationBlock($snapshot), default => null, }; if ($typeBlock !== null) { $settings[] = $typeBlock; } $settings = array_values(array_filter($settings)); return [ 'status' => 'ok', 'settings' => $settings, 'warnings' => $warnings, ]; } /** * @return array{type: string, title: string, entries: array}|null */ private function buildAutopilotBlock(array $snapshot): ?array { $entries = []; foreach ([ 'deviceNameTemplate' => 'Device name template', 'language' => 'Language', 'locale' => 'Locale', 'deploymentMode' => 'Deployment mode', 'deviceType' => 'Device type', 'enableWhiteGlove' => 'Pre-provisioning (White Glove)', 'hybridAzureADJoinSkipConnectivityCheck' => 'Skip Hybrid AAD connectivity check', ] as $key => $label) { $value = Arr::get($snapshot, $key); if (is_string($value) && $value !== '') { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_bool($value)) { $entries[] = ['key' => $label, 'value' => $value ? 'Enabled' : 'Disabled']; } } $oobe = Arr::get($snapshot, 'outOfBoxExperienceSettings'); if (is_array($oobe) && $oobe !== []) { $oobe = Arr::except($oobe, ['@odata.type']); foreach ($this->expandOutOfBoxExperienceEntries($oobe) as $entry) { $entries[] = $entry; } } $assignments = Arr::get($snapshot, 'assignments'); if (is_array($assignments) && $assignments !== []) { $entries[] = ['key' => 'Assignments (snapshot)', 'value' => '[present]']; } if ($entries === []) { return null; } return [ 'type' => 'keyValue', 'title' => 'Autopilot profile', 'entries' => $entries, ]; } /** * @return array */ private function expandOutOfBoxExperienceEntries(array $oobe): array { $knownKeys = [ 'hideEULA' => 'Hide EULA', 'userType' => 'User type', 'hideEscapeLink' => 'Hide escape link', 'deviceUsageType' => 'Device usage type', 'hidePrivacySettings' => 'Hide privacy settings', 'skipKeyboardSelectionPage' => 'Skip keyboard selection page', 'skipExpressSettings' => 'Skip express settings', ]; $entries = []; foreach ($knownKeys as $key => $label) { if (! array_key_exists($key, $oobe)) { continue; } $value = $oobe[$key]; if (is_bool($value)) { $entries[] = ['key' => "OOBE: {$label}", 'value' => $value ? 'Enabled' : 'Disabled']; } elseif (is_string($value) && $value !== '') { $entries[] = ['key' => "OOBE: {$label}", 'value' => $value]; } elseif (is_int($value) || is_float($value)) { $entries[] = ['key' => "OOBE: {$label}", 'value' => $value]; } unset($oobe[$key]); } foreach ($oobe as $key => $value) { $label = Str::headline((string) $key); if (is_bool($value)) { $entries[] = ['key' => "OOBE: {$label}", 'value' => $value ? 'Enabled' : 'Disabled']; } elseif (is_string($value) && $value !== '') { $entries[] = ['key' => "OOBE: {$label}", 'value' => $value]; } elseif (is_int($value) || is_float($value)) { $entries[] = ['key' => "OOBE: {$label}", 'value' => $value]; } elseif (is_array($value) && $value !== []) { $entries[] = ['key' => "OOBE: {$label}", 'value' => $value]; } } return $entries; } /** * @return array{type: string, title: string, entries: array}|null */ private function buildEnrollmentStatusPageBlock(array $snapshot): ?array { $entries = []; foreach ([ 'priority' => 'Priority', 'showInstallationProgress' => 'Show installation progress', 'blockDeviceSetupRetryByUser' => 'Block retry by user', 'allowDeviceResetOnInstallFailure' => 'Allow device reset on install failure', 'installProgressTimeoutInMinutes' => 'Install progress timeout (minutes)', 'allowLogCollectionOnInstallFailure' => 'Allow log collection on failure', ] as $key => $label) { $value = Arr::get($snapshot, $key); if (is_int($value) || is_float($value)) { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_string($value) && $value !== '') { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_bool($value)) { $entries[] = ['key' => $label, 'value' => $value ? 'Enabled' : 'Disabled']; } } $selected = Arr::get($snapshot, 'selectedMobileAppIds'); if (is_array($selected) && $selected !== []) { $entries[] = ['key' => 'Selected mobile app IDs', 'value' => array_values($selected)]; } $assigned = Arr::get($snapshot, 'assignments'); if (is_array($assigned) && $assigned !== []) { $entries[] = ['key' => 'Assignments (snapshot)', 'value' => '[present]']; } if ($entries === []) { return null; } return [ 'type' => 'keyValue', 'title' => 'Enrollment Status Page (ESP)', 'entries' => $entries, ]; } /** * @return array{type: string, title: string, entries: array}|null */ private function buildEnrollmentRestrictionBlock(array $snapshot): ?array { $entries = []; foreach ([ 'priority' => 'Priority', 'version' => 'Version', 'deviceEnrollmentConfigurationType' => 'Configuration type', ] as $key => $label) { $value = Arr::get($snapshot, $key); if (is_int($value) || is_float($value)) { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_string($value) && $value !== '') { $entries[] = ['key' => $label, 'value' => $value]; } } $platformRestrictions = Arr::get($snapshot, 'platformRestrictions'); $platformRestriction = Arr::get($snapshot, 'platformRestriction'); $platformPayload = is_array($platformRestrictions) && $platformRestrictions !== [] ? $platformRestrictions : (is_array($platformRestriction) ? $platformRestriction : null); if (is_array($platformPayload) && $platformPayload !== []) { $platformPayload = Arr::except($platformPayload, ['@odata.type']); $platformBlocked = Arr::get($platformPayload, 'platformBlocked'); if (is_bool($platformBlocked)) { $entries[] = ['key' => 'Platform blocked', 'value' => $platformBlocked ? 'Enabled' : 'Disabled']; } $personalBlocked = Arr::get($platformPayload, 'personalDeviceEnrollmentBlocked'); if (is_bool($personalBlocked)) { $entries[] = ['key' => 'Personal device enrollment blocked', 'value' => $personalBlocked ? 'Enabled' : 'Disabled']; } $osMin = Arr::get($platformPayload, 'osMinimumVersion'); $entries[] = [ 'key' => 'OS minimum version', 'value' => (is_string($osMin) && $osMin !== '') ? $osMin : 'None', ]; $osMax = Arr::get($platformPayload, 'osMaximumVersion'); $entries[] = [ 'key' => 'OS maximum version', 'value' => (is_string($osMax) && $osMax !== '') ? $osMax : 'None', ]; $blockedManufacturers = Arr::get($platformPayload, 'blockedManufacturers'); $entries[] = [ 'key' => 'Blocked manufacturers', 'value' => (is_array($blockedManufacturers) && $blockedManufacturers !== []) ? array_values($blockedManufacturers) : ['None'], ]; $blockedSkus = Arr::get($platformPayload, 'blockedSkus'); $entries[] = [ 'key' => 'Blocked SKUs', 'value' => (is_array($blockedSkus) && $blockedSkus !== []) ? array_values($blockedSkus) : ['None'], ]; } $assigned = Arr::get($snapshot, 'assignments'); if (is_array($assigned) && $assigned !== []) { $entries[] = ['key' => 'Assignments (snapshot)', 'value' => '[present]']; } if ($entries === []) { return null; } return [ 'type' => 'keyValue', 'title' => 'Enrollment restrictions', 'entries' => $entries, ]; } /** * @return array{type: string, title: string, entries: array}|null */ private function buildEnrollmentLimitBlock(array $snapshot): ?array { $entries = []; foreach ([ 'priority' => 'Priority', 'version' => 'Version', 'deviceEnrollmentConfigurationType' => 'Configuration type', 'limit' => 'Enrollment limit', 'limitType' => 'Limit type', ] as $key => $label) { $value = Arr::get($snapshot, $key); if (is_int($value) || is_float($value)) { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_string($value) && $value !== '') { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_bool($value)) { $entries[] = ['key' => $label, 'value' => $value ? 'Enabled' : 'Disabled']; } } $assigned = Arr::get($snapshot, 'assignments'); if (is_array($assigned) && $assigned !== []) { $entries[] = ['key' => 'Assignments (snapshot)', 'value' => '[present]']; } if ($entries === []) { return null; } return [ 'type' => 'keyValue', 'title' => 'Enrollment limits', 'entries' => $entries, ]; } /** * @return array{type: string, title: string, entries: array}|null */ private function buildEnrollmentPlatformRestrictionsBlock(array $snapshot): ?array { $entries = []; foreach ([ 'priority' => 'Priority', 'version' => 'Version', 'platformType' => 'Platform type', 'deviceEnrollmentConfigurationType' => 'Configuration type', ] as $key => $label) { $value = Arr::get($snapshot, $key); if (is_int($value) || is_float($value)) { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_string($value) && $value !== '') { $entries[] = ['key' => $label, 'value' => $value]; } } $platformPayload = Arr::get($snapshot, 'platformRestrictions') ?? Arr::get($snapshot, 'platformRestriction'); if (is_array($platformPayload) && $platformPayload !== []) { $prefix = (string) (Arr::get($snapshot, 'platformType') ?: 'Platform'); $this->appendPlatformRestrictionEntries($entries, $prefix, $platformPayload); } $typedRestrictions = [ 'androidForWorkRestriction' => 'Android work profile', 'androidRestriction' => 'Android', 'iosRestriction' => 'iOS/iPadOS', 'macRestriction' => 'macOS', 'windowsRestriction' => 'Windows', ]; foreach ($typedRestrictions as $key => $prefix) { $restriction = Arr::get($snapshot, $key); if (! is_array($restriction) || $restriction === []) { continue; } $this->appendPlatformRestrictionEntries($entries, $prefix, $restriction); } $assigned = Arr::get($snapshot, 'assignments'); if (is_array($assigned) && $assigned !== []) { $entries[] = ['key' => 'Assignments (snapshot)', 'value' => '[present]']; } if ($entries === []) { return null; } return [ 'type' => 'keyValue', 'title' => 'Platform restrictions (enrollment)', 'entries' => $entries, ]; } /** * @param array $entries */ private function appendPlatformRestrictionEntries(array &$entries, string $prefix, array $payload): void { $payload = Arr::except($payload, ['@odata.type']); $platformBlocked = Arr::get($payload, 'platformBlocked'); if (is_bool($platformBlocked)) { $entries[] = ['key' => "{$prefix}: Platform blocked", 'value' => $platformBlocked ? 'Enabled' : 'Disabled']; } $personalBlocked = Arr::get($payload, 'personalDeviceEnrollmentBlocked'); if (is_bool($personalBlocked)) { $entries[] = ['key' => "{$prefix}: Personal device enrollment blocked", 'value' => $personalBlocked ? 'Enabled' : 'Disabled']; } $osMin = Arr::get($payload, 'osMinimumVersion'); $entries[] = [ 'key' => "{$prefix}: OS minimum version", 'value' => (is_string($osMin) && $osMin !== '') ? $osMin : 'None', ]; $osMax = Arr::get($payload, 'osMaximumVersion'); $entries[] = [ 'key' => "{$prefix}: OS maximum version", 'value' => (is_string($osMax) && $osMax !== '') ? $osMax : 'None', ]; $blockedManufacturers = Arr::get($payload, 'blockedManufacturers'); $entries[] = [ 'key' => "{$prefix}: Blocked manufacturers", 'value' => (is_array($blockedManufacturers) && $blockedManufacturers !== []) ? array_values($blockedManufacturers) : ['None'], ]; $blockedSkus = Arr::get($payload, 'blockedSkus'); $entries[] = [ 'key' => "{$prefix}: Blocked SKUs", 'value' => (is_array($blockedSkus) && $blockedSkus !== []) ? array_values($blockedSkus) : ['None'], ]; } /** * @return array{type: string, title: string, entries: array}|null */ private function buildEnrollmentNotificationBlock(array $snapshot): ?array { $entries = []; foreach ([ 'priority' => 'Priority', 'version' => 'Version', 'deviceEnrollmentConfigurationType' => 'Configuration type', 'defaultLocale' => 'Default locale', 'notificationMessageTemplateId' => 'Notification message template ID', ] as $key => $label) { $value = Arr::get($snapshot, $key); if (is_int($value) || is_float($value)) { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_string($value) && $value !== '') { $entries[] = ['key' => $label, 'value' => $value]; } elseif (is_bool($value)) { $entries[] = ['key' => $label, 'value' => $value ? 'Enabled' : 'Disabled']; } } $notificationMessages = Arr::get($snapshot, 'notificationMessages'); if (is_array($notificationMessages) && $notificationMessages !== []) { $entries[] = ['key' => 'Notification messages', 'value' => sprintf('%d item(s)', count($notificationMessages))]; } $assigned = Arr::get($snapshot, 'assignments'); if (is_array($assigned) && $assigned !== []) { $entries[] = ['key' => 'Assignments (snapshot)', 'value' => '[present]']; } if ($entries === []) { return null; } return [ 'type' => 'keyValue', 'title' => 'Enrollment notifications', 'entries' => $entries, ]; } /** * @return array */ public function flattenForDiff(?array $snapshot, string $policyType, ?string $platform = null): array { $normalized = $this->normalize($snapshot ?? [], $policyType, $platform); return $this->defaultNormalizer->flattenNormalizedForDiff($normalized); } }