resolveTenantOrNull(); $dryRun = ! (bool) $this->option('write'); $query = Policy::query() ->with(['tenant']) ->active() ->where('policy_type', 'enrollmentRestriction'); if ($tenant) { $query->where('tenant_id', $tenant->id); } $candidates = $query->get(); $changedVersions = 0; $changedPolicies = 0; $ignoredPolicies = 0; foreach ($candidates as $policy) { $latestVersion = $policy->versions()->latest('version_number')->first(); $snapshot = $latestVersion?->snapshot; if (! is_array($snapshot)) { $snapshot = $this->fetchSnapshotOrNull($policy); } if (! is_array($snapshot)) { continue; } if (! $this->isEspSnapshot($snapshot)) { continue; } $this->line(sprintf( 'ESP detected: policy=%s tenant_id=%s external_id=%s', (string) $policy->getKey(), (string) $policy->tenant_id, (string) $policy->external_id, )); if ($dryRun) { continue; } $existingTarget = Policy::query() ->where('tenant_id', $policy->tenant_id) ->where('external_id', $policy->external_id) ->where('policy_type', 'windowsEnrollmentStatusPage') ->first(); if ($existingTarget) { $policy->forceFill(['ignored_at' => now()])->save(); $ignoredPolicies++; continue; } $policy->forceFill([ 'policy_type' => 'windowsEnrollmentStatusPage', ])->save(); $changedPolicies++; $changedVersions += PolicyVersion::query() ->where('policy_id', $policy->id) ->where('policy_type', 'enrollmentRestriction') ->update(['policy_type' => 'windowsEnrollmentStatusPage']); } $this->info('Done.'); $this->info('PolicyVersions changed: '.$changedVersions); $this->info('Policies changed: '.$changedPolicies); $this->info('Policies ignored: '.$ignoredPolicies); $this->info('Mode: '.($dryRun ? 'dry-run' : 'write')); return Command::SUCCESS; } private function isEspSnapshot(array $snapshot): bool { $odataType = $snapshot['@odata.type'] ?? null; $configurationType = $snapshot['deviceEnrollmentConfigurationType'] ?? null; return (is_string($odataType) && strcasecmp($odataType, '#microsoft.graph.windows10EnrollmentCompletionPageConfiguration') === 0) || (is_string($configurationType) && $configurationType === 'windows10EnrollmentCompletionPageConfiguration'); } private function fetchSnapshotOrNull(Policy $policy): ?array { $tenant = $policy->tenant; if (! $tenant) { return null; } $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; $response = $this->graphClient->getPolicy('enrollmentRestriction', $policy->external_id, [ 'tenant' => $tenantIdentifier, 'client_id' => $tenant->app_client_id, 'client_secret' => $tenant->app_client_secret, 'platform' => $policy->platform, ]); if ($response->failed()) { return null; } $payload = $response->data['payload'] ?? null; return is_array($payload) ? $payload : null; } private function resolveTenantOrNull(): ?Tenant { $tenantOption = $this->option('tenant'); if (! $tenantOption) { return null; } return Tenant::query() ->forTenant($tenantOption) ->firstOrFail(); } }