invocationEnabled) { return $this->blocked('runtime_blocked_feature_disabled', [ 'runtime_state' => 'blocked_feature_disabled', ]); } if (! $policy->productionRunnerEnabled) { return $this->blocked('runtime_blocked_runner_disabled', [ 'runtime_state' => 'blocked_runner_disabled', ]); } if (! $policy->environmentAllowed()) { return $this->blocked('runtime_blocked_environment_not_allowed', [ 'runtime_state' => 'environment_not_allowed', 'runtime_environment' => $policy->currentEnvironment, ]); } if (! $policy->timeoutPolicyValid()) { return $this->blocked('runtime_blocked_timeout_policy_missing', [ 'runtime_state' => 'timeout_policy_missing', ]); } if (! $policy->tempPolicySafe()) { return $this->blocked('runtime_blocked_temp_policy_unsafe', [ 'runtime_state' => 'temp_policy_unsafe', ]); } if (! $this->executor->available()) { return $this->blocked('runtime_blocked_process_executor_missing', [ 'runtime_state' => 'process_executor_missing', ]); } $powershell = $this->executor->run(new ExchangePowerShellProcessCommand( arguments: [ $policy->powershellBinary, '-NoLogo', '-NoProfile', '-NonInteractive', '-Command', '$PSVersionTable.PSVersion.ToString()', ], timeoutSeconds: $policy->checkTimeoutSeconds, stdoutMaxBytes: 4096, stderrMaxBytes: 4096, )); if ($powershell->timedOut || $powershell->exitCode !== 0 || trim($powershell->stdout) === '') { return $this->blocked('runtime_blocked_powershell_missing', [ 'runtime_state' => 'powershell_missing', ]); } if (! $policy->moduleCheckEnabled) { return ExchangePowerShellGateResult::allowed([ 'runtime_state' => 'ready', 'module_state' => 'unchecked', ]); } $module = $this->executor->run(new ExchangePowerShellProcessCommand( arguments: [ $policy->powershellBinary, '-NoLogo', '-NoProfile', '-NonInteractive', '-Command', 'Get-Module -ListAvailable -Name ExchangeOnlineManagement', ], timeoutSeconds: $policy->checkTimeoutSeconds, stdoutMaxBytes: 4096, stderrMaxBytes: 4096, )); if ($module->timedOut || $module->exitCode !== 0) { return $this->blocked('runtime_blocked_exchange_module_unknown', [ 'runtime_state' => 'exchange_module_unknown', ]); } if (! str_contains(trim($module->stdout), 'ExchangeOnlineManagement')) { return $this->blocked('runtime_blocked_exchange_module_missing', [ 'runtime_state' => 'exchange_module_missing', ]); } return ExchangePowerShellGateResult::allowed([ 'runtime_state' => 'ready', 'module_state' => 'available', ]); } catch (Throwable) { return ExchangePowerShellGateResult::blocked( reasonCode: ProviderReasonCodes::UnknownError, failureCode: 'runtime_failed_unexpected', message: 'Exchange PowerShell runtime readiness failed safely.', context: ['runtime_state' => 'unexpected_failure'], ); } } /** * @param array $context */ private function blocked(string $failureCode, array $context): ExchangePowerShellGateResult { return ExchangePowerShellGateResult::blocked( reasonCode: ProviderReasonCodes::ProviderBindingUnsupported, failureCode: $failureCode, message: 'Exchange PowerShell runtime readiness is not satisfied.', context: $context, ); } }