Skip to main content

Keeping EWS Enabled for Cloud Platform: Configuration and Verification Guide

For license details, see Plans and pricing.

From October 2026, Exchange Online blocks all EWS traffic when EWS is enabled and the tenant's EwsAllowedAppIDs list is empty. To keep Cloud Platform access to EWS, add the Cloud Platform App IDs to this list and turn on EWS for your tenant.

This article covers two ways to do this:

  • Manually: Follow Option 1: Configure EWS manually, then confirm the result with the Verification checklist.

  • With a script: Run the PowerShell script in Option 2: Configure EWS using the script. It does the same steps automatically and verifies the result.

It also covers how to roll back the change and troubleshoot common EWS errors.

Overview

Cloud Platform uses Exchange Web Services (EWS) to access resources which are not available through Graph. Two organization-level settings control this:

Configuration

Purpose

Required

Global EWS enablement (EwsEnabled)

Turns EWS on for the Exchange Online tenant.

Required

Allowed application IDs (EwsAllowedAppIDs)

When EwsEnabled is True, only the Enterprise applications in this list can use EWS. Cloud Platform's App IDs must be in it.

Required (from October 2026, an empty list blocks all EWS traffic)

Both options do the following, in order:

  1. Retrieves the tenant's current EwsAllowedAppIDs list.

  2. Finds Cloud Platform's App IDs in the tenant's Enterprise Applications.

  3. Adds any missing Cloud Platform App IDs without removing the App IDs that are already configured.

  4. Sets EwsEnabled to True.

How the allow list behaves

  • EwsAllowedAppIDs is enforced only when EwsEnabled is True. When EwsEnabled is blank ($null), the list is ignored. When EwsEnabled is False, all EWS traffic is blocked whatever the list contains.

  • When EwsEnabled is True, only the applications in the list can use EWS. From October 2026, if the list is empty, all EWS traffic is blocked.

  • If the list is empty today, this guide adds the Cloud Platform App IDs to it. Any other application that needs EWS must also have its App ID in the list.

  • Changes to EwsAllowedAppIDs can take up to 24 hours to take effect because of caching. Changes to EwsEnabled usually take effect within 1 hour, but can take up to 4 hours.

Prerequisites

Requirement

Details

Shell

Azure Cloud Shell (PowerShell) or PowerShell 7+

Exchange Online PowerShell

ExchangeOnlineManagement module (pre-installed in Cloud Shell)

Azure CLI

az (pre-installed in Cloud Shell)

Roles

Exchange Administrator (or Organization Management) to change the organization config, plus at least Directory Readers to list Enterprise Applications

Before you start, sign in to Exchange Online PowerShell (for Steps 1, 3 and 4) and to Azure CLI (for Step 2).


Option 1: Configure EWS manually

Run Steps 1 to 4 in order, then run the Verification checklist.

Step 1: Retrieve the current EwsAllowedAppIDs list

EwsAllowedAppIDs is returned only when you add the -RetrieveEwsOperationAccessPolicy switch.

Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy |     Format-List EwsAllowedAppIDs

Example output:

EwsAllowedAppIDs : aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee,11111111-2222-3333-4444-555555555555

Save this value. You need it in Step 3, and it is your rollback point.

To show one App ID per line, which is easier to compare:

(Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy).EwsAllowedAppIDs -split ',' |     ForEach-Object { $_.Trim() } | Where-Object { $_ }

📝NOTE:

  • The value is a single comma-separated string, not a list.

  • The list may already contain App IDs that your administrators added, or that Microsoft added automatically based on your tenant's recent EWS usage. Keep all of them; Step 3 only adds to the list.

  • A blank result means no App IDs are allowed. While EwsEnabled is True, that blocks all EWS traffic.


Step 2: Get Cloud Platform's App IDs from the tenant's Enterprise Applications

2.1 List the Cloud Platform service principals

az ad sp list --all `   --query "[?starts_with(displayName, 'Druva inSync Exchange') || starts_with(displayName, 'Druva M365')].{Name:displayName,AppId:appId}" `   -o table

Example output:

Name                          AppId                                  ----------------------------  ------------------------------------  Druva Exchange <...>          <druva-app-id-1>                      ...

2.2 Write down the Cloud Platform App IDs

Use the AppId column (not ObjectId). Example:

<druva-app-id-1> 
<druva-app-id-2>


Step 3: Add the missing Cloud Platform App IDs without removing existing ones

Set-OrganizationConfig -EwsAllowedAppIDs does not support adding or removing individual App IDs. Every call replaces the whole list. To add App IDs, Microsoft's method is to read the current list, add the new App IDs to it, and write the full list back. That is what this step does.

3.1 Compare the two lists

Using the outputs of Step 1 and Step 2, find the Cloud Platform App IDs that are not in the current list. GUID comparison is not case-sensitive.

  • If all Cloud Platform App IDs are already present, no change is needed. Go to Step 4.

  • If any Cloud Platform App ID is missing, continue to 3.2.

  • If the current list is empty, all Cloud Platform App IDs are missing. Continue to 3.2; the new list will contain only the Cloud Platform App IDs.

3.2 Option A: Set the merged value by hand

Build one comma-separated string: all existing App IDs from Step 1, followed by the missing Cloud Platform App IDs.

Set-OrganizationConfig -EwsAllowedAppIDs "<Existing-App-ID-1>,<Existing-App-ID-2>,<Druva-App-ID-1>,<Druva-App-ID-2>"

❗IMPORTANT: Copy every existing App ID exactly. Any App ID you leave out is removed from the allow list, and that application is blocked from EWS.

3.3 Option B: Merge with PowerShell (recommended)

This reads the live value, adds only the missing Cloud Platform App IDs, and writes the combined list back. It also handles an empty list and skips App IDs that are already present. Replace the placeholders with the App IDs from Step 2.2.

# Druva App IDs from Step 2.2 $druvaAppIds = @(     '<druva-app-id-1>',     '<druva-app-id-2>' )  # Current list (Step 1) $currentValue = (Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy).EwsAllowedAppIDs $existing = @($currentValue -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ }) Write-Host "Current list (save for rollback): $currentValue"  # Druva App IDs not in the current list (-notcontains is case-insensitive) $missing = @($druvaAppIds | Where-Object { $existing -notcontains $_ })  if ($missing.Count -eq 0) {     Write-Host "All Druva App IDs are already present. No change needed." } else {     $merged = ($existing + $missing) -join ','     Write-Host "Adding: $($missing -join ', ')"     Write-Host "New list: $merged"     Set-OrganizationConfig -EwsAllowedAppIDs $merged }

3.4 Confirm the list before you continue

Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy |     Format-List EwsAllowedAppIDs

Confirm that every Cloud Platform App ID from Step 2.2 and every App ID from Step 1 is in the list. Do not continue to Step 4 until it is.

3.5 Rollback

If the list was not blank in Step 1, restore the value you saved:

Set-OrganizationConfig -EwsAllowedAppIDs "<value saved in Step 1>"

If the list was blank in Step 1, do not clear it once EWS is enabled. While EwsEnabled is True, an empty list blocks all EWS traffic, including Cloud Platform's.


Step 4: Verify and enable EWS globally

The organization-wide setting determines whether EWS is available at all. Enabling it also turns on enforcement of the list you prepared in Step 3.

4.1 Check the current configuration

Get-OrganizationConfig | Select-Object EwsEnabled

Possible output:

EwsEnabled : True

or

EwsEnabled :

If the value is already True, no change is needed. Go to the verification checklist.

Changes to EwsAllowedAppIDs can take up to 24 hours to reach every Exchange Online server. If EwsEnabled is currently blank and EWS is working, you can wait up to 24 hours after Step 3 before you run 4.2. This makes it less likely that EWS access is briefly interrupted for applications in the list.

4.2 Enable EWS (if False or blank)

Set-OrganizationConfig -EwsEnabled $true

4.3 Verify

Get-OrganizationConfig | Select-Object EwsEnabled

Expected:

EwsEnabled : True


Verification checklist

Check 1: EWS is enabled

Get-OrganizationConfig | Select-Object EwsEnabled

✅ EwsEnabled is True.

Check 2: All Cloud Platform App IDs are in EwsAllowedAppIDs

Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy |     Format-List EwsAllowedAppIDs

Or check each Cloud Platform App ID automatically. This uses $druvaAppIds from Step 3.3, so run it in the same PowerShell session.

$allowed = @((Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy).EwsAllowedAppIDs -split ',' |     ForEach-Object { $_.Trim() } | Where-Object { $_ })  $druvaAppIds | ForEach-Object {     [pscustomobject]@{ AppId = $_; Present = ($allowed -contains $_) } } | Format-Table

✅ Every Cloud Platform App ID shows Present = True.

✅ Every App ID that was in the list in Step 1 is still there.


Troubleshooting

Symptom

Likely cause

Cloud Platform still cannot reach EWS right after the change

EwsAllowedAppIDs changes can take up to 24 hours to take effect, and EwsEnabled changes up to 4 hours. Wait before you test again.

HTTP 403 with header X-EWS-Policy-Reason: EWS is disabled for this user or tenant

EwsEnabled is False for the organization, or EWS is disabled on the mailbox.

HTTP 403 with header X-EWS-Policy-Reason: EWS is blocked by policy for this user or tenant

The Cloud Platform App ID is not in EwsAllowedAppIDs. Repeat Check 2.

Other EWS applications stopped working after the change

They are not in EwsAllowedAppIDs. Add their App IDs using the method in Step 3.3, or roll back (Step 3.5).

EwsAllowedAppIDs is missing from the output

Add -RetrieveEwsOperationAccessPolicy to Get-OrganizationConfig.

Option 2: Configure EWS using the script

The script runs Steps 1 to 4 of this guide, in the same order, and then runs the verification checklist. It saves the current EwsAllowedAppIDs list to a backup file before it makes any change.

Run these steps with a script

The script runs Steps 1 to 4 of this guide, in the same order, and then runs the verification checklist. It saves the current EwsAllowedAppIDs list to a backup file before it makes any change.

Run the script

The commands below assume you saved the Full script as ews_druva_allowed_appids.ps1.

  1. Open Azure Cloud Shell (PowerShell) or PowerShell 7+.

  2. Preview the changes. The script writes nothing.

./ews_druva_allowed_appids.ps1 -WhatIf -v
  1. Run all steps. The script asks you to confirm each change.

./ews_druva_allowed_appids.ps1 -vCheck the verification output at the end of the run. A successful run ends with [OK] Verification passed. If a check fails, the script shows a [FAIL] line and exits with code 1.

To skip the confirmation prompts, add -Confirm:$false.

To follow the 24-hour wait in 4.1, decline the prompt to set EwsEnabled, then run the script again after the wait. The first run reports [FAIL] EwsEnabled = '', which is expected. The second run makes no list change and turns on EWS.

Parameters

Parameter

Description

-NamePrefixes

Display-name prefixes used to find the Cloud Platform applications. Matching is case-sensitive. Default: Druva inSync Exchange, Druva M365

-TenantId

Optional. Tenant ID to sign in to with Azure CLI, and to check the Exchange Online session against.

-UseDeviceCode

Uses device-code sign-in for Exchange Online and Azure CLI (for machines without a browser).

-BackupFolder

Folder for the backup of the current list. Default: $HOME

-v

Shows detailed output.

-WhatIf

Shows what would change. Writes nothing.

-Confirm:$false

Runs all steps without prompting.

-Help

Shows help and exits.

Script behavior

Stage

What the script does

Sign-in

Reuses existing Exchange Online and Azure CLI sessions, and signs in only when none exists. In Azure Cloud Shell, Azure CLI is already signed in, and Exchange Online falls back to device code. Outside Cloud Shell, it uses browser sign-in, or device code with -UseDeviceCode. Installs the ExchangeOnlineManagement module if it is missing.

Tenant check

Stops if Exchange Online and Azure CLI are signed in to different tenants. Otherwise, App IDs from one tenant would be written into another tenant's allow list.

Step 1

Saves the current list to EwsAllowedAppIDs-backup-<yyyyMMdd-HHmmss>.txt in the backup folder.

Step 2

Skips Microsoft first-party applications. Prefixes such as Office 365 also match these. Listing can take a few minutes in large tenants.

Step 3

Uses Option B (3.3).

Before Step 4

Reads the list again. If any App ID is missing, stops and does not change EwsEnabled.

Step 4

Makes no change if EwsEnabled is already True.

Verification

Runs Check 1 and Check 2, and checks that no existing App ID was removed.

End of run

If the list changed and was not empty, shows the rollback command: Set-OrganizationConfig -EwsAllowedAppIDs (Get-Content '<backup file path>'). Disconnects Exchange Online only if the script opened the session.

Script troubleshooting

Script message

Action

Azure CLI (az) not found.

Use Azure Cloud Shell or install Azure CLI.

Azure CLI sign-in failed.

Sign in again, or use -UseDeviceCode.

Exchange Online (...) and Azure CLI (...) are signed in to different tenants.

Sign in to the same tenant and re-run.

Exchange Online is signed in to tenant ..., not ...

Sign in to the tenant passed in -TenantId.

Set-OrganizationConfig is not available.

Sign in with an Exchange Administrator account.

Set-OrganizationConfig does not accept -EwsAllowedAppIDs in this tenant yet.

Microsoft's rollout has not reached the tenant; try again later.

az ad sp list failed.

Check that you have Directory Readers or higher.

No Druva applications found for prefixes: ...

Check the names (matching is case-sensitive). Set them with -NamePrefixes.

Druva App IDs are not in the list: ... EwsEnabled was not changed.

Repeat Check 2. EWS was not turned on.

Script

<# .SYNOPSIS Adds Druva's App IDs to EwsAllowedAppIDs without removing existing entries, then turns on EWS for the tenant.  .DESCRIPTION Automates docs/EWS_Druva_AllowedAppIds_Guide.md, in the same order:   1. Reads the current EwsAllowedAppIDs list and saves it to a backup file.   2. Finds Druva's App IDs in the tenant's Enterprise Applications (az ad sp list, name-prefix filter),      excluding Microsoft first-party applications.   3. Adds the missing Druva App IDs. Set-OrganizationConfig -EwsAllowedAppIDs replaces the whole list,      so the script reads the current list, appends the missing IDs, and writes the full value back.      If the list is empty, it is populated with the Druva App IDs.   4. Sets EwsEnabled to $true, only after the list is confirmed to contain every Druva App ID.   5. Verifies EwsEnabled is True, every Druva App ID is in the list, and no existing App ID was removed.  The list is updated before EWS is turned on because EwsAllowedAppIDs is enforced only once EwsEnabled is True. Turning on EWS first with an empty list would block all EWS traffic, including Druva's.  Changes to EwsAllowedAppIDs can take up to 24 hours to take effect; changes to EwsEnabled up to 4 hours.  Sign-in:   - Reuses existing Exchange Online and Azure CLI sessions; signs in only when there is none.   - In Azure Cloud Shell, Azure CLI is already signed in. Exchange Online falls back to device code.   - Outside Cloud Shell, uses browser sign-in, or device code with -UseDeviceCode.   - Stops if Exchange Online and Azure CLI are signed in to different tenants.   - Disconnects Exchange Online at the end only if this script opened the session.  Requirements:   - Azure Cloud Shell (PowerShell) or PowerShell 7+   - ExchangeOnlineManagement module (installed automatically if missing)   - Azure CLI (az)   - Exchange Administrator (to change the org config) and Directory Readers or higher (to list Enterprise Applications)  .PARAMETER NamePrefixes Display-name prefixes used to find Druva applications. Matching is case-sensitive. Default: 'Druva Exchange', 'Office 365'  .PARAMETER TenantId Optional. Tenant ID to sign in to with Azure CLI, and to check the Exchange Online session against.  .PARAMETER UseDeviceCode Use device-code sign-in for Exchange Online and Azure CLI (for machines without a browser).  .PARAMETER BackupFolder Folder for the backup of the current list. Default: $HOME  .PARAMETER v Verbose output.  .PARAMETER Help Show help and exit.  .EXAMPLE ./ews_druva_allowed_appids.ps1 -WhatIf -v Show what would change. Nothing is written.  .EXAMPLE ./ews_druva_allowed_appids.ps1 -v Run all steps. Prompts before each change.  .EXAMPLE ./ews_druva_allowed_appids.ps1 -Confirm:$false Run all steps without prompting.  .EXAMPLE ./ews_druva_allowed_appids.ps1 -UseDeviceCode -TenantId 00000000-0000-0000-0000-000000000000 Sign in with device code to a specific tenant.  .NOTES Source: https://techcommunity.microsoft.com/blog/exchange/introducing-ewsallowedappids-preparing-for-the-final-phase-of-ews-retirement/4529471 #>  [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param(     [string[]]$NamePrefixes = @('Druva inSync Exchange', 'Druva M365'),     [string]$TenantId = "",     [switch]$UseDeviceCode,     [string]$BackupFolder = "$HOME",     [switch]$v,     [switch]$Help )  if ($Help) {     Get-Help $MyInvocation.MyCommand.Path -Detailed     exit 0 }  $ErrorActionPreference = 'Stop'  # Owner tenants of Microsoft first-party applications. Prefixes such as 'Office 365' also match these. $MicrosoftTenantIds = @('f8cdef31-a31e-4b4a-93e4-5f571e91255a', '72f988bf-86f1-41af-91ab-2d7cd011db47') $IsCloudShell = ($env:AZUREPS_HOST_ENVIRONMENT -like 'cloud-shell*') -or [bool]$env:ACC_CLOUD  function Write-Info($msg) { if ($v) { Write-Host "[INFO] $msg" -ForegroundColor Cyan } } function Write-Ok($msg)   { Write-Host "[OK] $msg" -ForegroundColor Green } function Write-Warn($msg) { Write-Host "[WARN] $msg" -ForegroundColor Yellow } function Write-Fail($msg) { Write-Host "[FAIL] $msg" -ForegroundColor Red }  function Get-AllowedAppIds {     # EwsAllowedAppIDs is only returned with -RetrieveEwsOperationAccessPolicy.     $raw = (Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy).EwsAllowedAppIDs     @($raw -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ }) }  # ----- 0. Prerequisites --------------------------------------------------- if (-not (Get-Command az -ErrorAction SilentlyContinue)) {     throw "Azure CLI (az) not found. Use Azure Cloud Shell or install Azure CLI." } if (-not (Get-Module -ListAvailable ExchangeOnlineManagement)) {     Write-Info "Installing ExchangeOnlineManagement module..."     Install-Module ExchangeOnlineManagement -Scope CurrentUser -Force } Import-Module ExchangeOnlineManagement -ErrorAction Stop Write-Info "Environment: $(if ($IsCloudShell) { 'Azure Cloud Shell' } else { 'Local PowerShell' })"  # ----- Sign in: Azure CLI ------------------------------------------------- Write-Info "Checking Azure CLI sign-in..." $azAccount = az account show -o json 2>$null if ($LASTEXITCODE -ne 0 -or ($TenantId -and (($azAccount -join "`n") | ConvertFrom-Json).tenantId -ne $TenantId)) {     Write-Info "Signing in to Azure CLI..."     $azArgs = @('login', '--allow-no-subscriptions', '-o', 'none')     if ($TenantId) { $azArgs += @('--tenant', $TenantId) }     if ($UseDeviceCode -or $IsCloudShell) { $azArgs += '--use-device-code' }     az @azArgs     if ($LASTEXITCODE -ne 0) { throw "Azure CLI sign-in failed." }     $azAccount = az account show -o json } $azTenantId = (($azAccount -join "`n") | ConvertFrom-Json).tenantId Write-Info "Azure CLI tenant: $azTenantId"  # ----- Sign in: Exchange Online ------------------------------------------- Write-Info "Checking Exchange Online sign-in..." $exoOpenedByScript = $false $exoConnection = $null try { $exoConnection = Get-ConnectionInformation -ErrorAction SilentlyContinue | Where-Object { $_.State -eq 'Connected' } | Select-Object -First 1 } catch { }  if (-not $exoConnection) {     Write-Info "Signing in to Exchange Online..."     if ($UseDeviceCode) {         Connect-ExchangeOnline -Device -ShowBanner:$false -ErrorAction Stop     } else {         try { Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop }         catch {             Write-Warn "Sign-in failed, trying device code."             Connect-ExchangeOnline -Device -ShowBanner:$false -ErrorAction Stop         }     }     $exoOpenedByScript = $true     $exoConnection = Get-ConnectionInformation | Where-Object { $_.State -eq 'Connected' } | Select-Object -First 1 } else {     Write-Info "Using existing Exchange Online session ($($exoConnection.UserPrincipalName))." }  try {     # Both sessions must point at the same tenant, otherwise App IDs from one tenant     # would be written into another tenant's allow list.     $exoTenantId = "$($exoConnection.TenantID)"     Write-Info "Exchange Online tenant: $exoTenantId"     if ($exoTenantId -and $exoTenantId -ne $azTenantId) {         throw "Exchange Online ($exoTenantId) and Azure CLI ($azTenantId) are signed in to different tenants. Sign in to the same tenant and re-run."     }     if ($TenantId -and $exoTenantId -and $exoTenantId -ne $TenantId) {         throw "Exchange Online is signed in to tenant $exoTenantId, not $TenantId."     }      # Missing cmdlet or parameter means the account lacks the role, or Microsoft's rollout has not reached the tenant.     $setCmd = Get-Command Set-OrganizationConfig -ErrorAction SilentlyContinue     if (-not $setCmd) {         throw "Set-OrganizationConfig is not available. Sign in with an Exchange Administrator account."     }     if (-not $setCmd.Parameters.ContainsKey('EwsAllowedAppIDs')) {         throw "Set-OrganizationConfig does not accept -EwsAllowedAppIDs in this tenant yet. Microsoft's rollout has not reached it; try again later."     }      # ----- Step 1: current list -------------------------------------------     Write-Host "`n== Step 1: Current EwsAllowedAppIDs ==" -ForegroundColor Cyan     $existing = Get-AllowedAppIds     if ($existing.Count -eq 0) { Write-Host "  (empty)" } else { $existing | ForEach-Object { Write-Host "  $_" } }      $backupPath = Join-Path $BackupFolder ("EwsAllowedAppIDs-backup-{0}.txt" -f (Get-Date -Format 'yyyyMMdd-HHmmss'))     ($existing -join ',') | Out-File -FilePath $backupPath -Encoding ASCII     Write-Host "Current list saved to $backupPath"      # ----- Step 2: Druva App IDs ------------------------------------------     Write-Host "`n== Step 2: Druva App IDs from Enterprise Applications ==" -ForegroundColor Cyan     $conditions = ($NamePrefixes | ForEach-Object { "starts_with(displayName, '$($_ -replace "'", "''")')" }) -join ' || '     $query = "[?$conditions].{Name:displayName,AppId:appId,Owner:appOwnerOrganizationId}"     Write-Info "Listing Enterprise Applications (can take a few minutes in large tenants)..."     $json = az ad sp list --all --query $query -o json     if ($LASTEXITCODE -ne 0) { throw "az ad sp list failed. Check that you have Directory Readers or higher." }     $found = @(($json -join "`n") | ConvertFrom-Json)      foreach ($s in @($found | Where-Object { $MicrosoftTenantIds -contains $_.Owner })) {         Write-Info "Skipping Microsoft first-party app: $($s.Name) ($($s.AppId))"     }     $found = @($found | Where-Object { $MicrosoftTenantIds -notcontains $_.Owner })      if ($found.Count -eq 0) {         throw "No Druva applications found for prefixes: $($NamePrefixes -join ', '). Check the names (matching is case-sensitive)."     }     $found | Format-Table Name, AppId -AutoSize | Out-String | Write-Host     $druvaAppIds = @($found.AppId | Where-Object { $_ } | Sort-Object -Unique)      # ----- Step 3: add missing, keep existing -----------------------------     Write-Host "`n== Step 3: Add missing Druva App IDs ==" -ForegroundColor Cyan     $missing = @($druvaAppIds | Where-Object { $existing -notcontains $_ })     $listUpdated = $false     if ($missing.Count -eq 0) {         Write-Ok "All Druva App IDs are already in EwsAllowedAppIDs. No change needed."     } else {         Write-Host "Missing: $($missing -join ', ')"         if ($existing.Count -eq 0) {             Write-Warn "The list is empty. Once EWS is on, only the applications in the list can use EWS."         }         $merged = ($existing + $missing) -join ','         Write-Host "New list: $merged"         if ($PSCmdlet.ShouldProcess('EwsAllowedAppIDs', "Write $($existing.Count + $missing.Count) App IDs (adds $($missing.Count))")) {             Set-OrganizationConfig -EwsAllowedAppIDs $merged             $listUpdated = $true             Write-Ok "EwsAllowedAppIDs updated."         }     }      if ($WhatIfPreference) {         Write-Host "`n== Step 4: Turn on EWS ==" -ForegroundColor Cyan         Write-Host "What if: EwsEnabled would be set to True if it is not already."         Write-Warn "-WhatIf: nothing was changed, so verification is skipped."         return     }      # Do not turn on EWS unless the list holds every Druva App ID.     $allowedNow = Get-AllowedAppIds     $stillMissing = @($druvaAppIds | Where-Object { $allowedNow -notcontains $_ })     if ($stillMissing.Count -gt 0) {         throw "Druva App IDs are not in the list: $($stillMissing -join ', '). EwsEnabled was not changed."     }      # ----- Step 4: EwsEnabled ---------------------------------------------     Write-Host "`n== Step 4: Turn on EWS ==" -ForegroundColor Cyan     $ewsEnabled = (Get-OrganizationConfig).EwsEnabled     Write-Host "Current EwsEnabled: '$ewsEnabled'"     if ($ewsEnabled -eq $true) {         Write-Ok "EwsEnabled is already True."     } elseif ($PSCmdlet.ShouldProcess('Organization config', 'Set EwsEnabled to $true')) {         Set-OrganizationConfig -EwsEnabled $true         Write-Ok "EwsEnabled set to True."     }      # ----- Verification ---------------------------------------------------     Write-Host "`n== Verification ==" -ForegroundColor Cyan     $failed = $false     $ewsNow = (Get-OrganizationConfig).EwsEnabled     if ($ewsNow -eq $true) { Write-Ok "EwsEnabled = True" } else { Write-Fail "EwsEnabled = '$ewsNow'"; $failed = $true }      $allowedNow = Get-AllowedAppIds     foreach ($id in $druvaAppIds) {         if ($allowedNow -contains $id) { Write-Ok "Druva App ID present: $id" }         else { Write-Fail "Druva App ID missing: $id"; $failed = $true }     }     foreach ($id in $existing) {         if ($allowedNow -notcontains $id) { Write-Fail "Existing App ID was removed: $id"; $failed = $true }     }      if ($listUpdated) {         if ($existing.Count -gt 0) {             Write-Host "To undo the list change: Set-OrganizationConfig -EwsAllowedAppIDs (Get-Content '$backupPath')"         } else {             Write-Host "The list was empty before. Do not clear it: once EWS is on, an empty list blocks all EWS traffic."         }     }     Write-Warn "Changes to EwsAllowedAppIDs can take up to 24 hours to take effect, and EwsEnabled up to 4 hours."     if ($failed) { exit 1 }     Write-Ok "Verification passed." } finally {     if ($exoOpenedByScript) {         Write-Info "Disconnecting the Exchange Online session opened by this script..."         Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue     } }
Did this answer your question?