# UCC.Site.Creator - Modernized

UCC Creator script for deploying AnywhereNow UCC Config Template v8.x sites to SharePoint Online.

## Version: 8.4.1.9

This version is **fully modernized** and **MC1117115 compliant**. It uses SPFx components exclusively for UI customizations, eliminating the need for Custom Script permissions.

### Requirements

- **PowerShell 7.4.6+** (PowerShell 7.x required, Windows PowerShell 5.1 is NOT supported)
- **PnP.PowerShell v3.1.0** (bundled - no separate installation needed)
- **Entra ID App Registration** with either:
  - `Sites.FullControl.All` — standard model (tenant app catalog)
  - `Sites.Selected` — restricted model (site collection app catalog, no tenant admin required after initial setup)

## Quick Start

### STEP 1: Tenant Setup (one-time per customer tenant)

```powershell
# Interactive authentication
.\Deploy-UccDashboard.ps1 -TenantUrl "https://contoso.sharepoint.com" -Interactive -ClientId "your-app-id"

# Certificate authentication (for automation)
.\Deploy-UccDashboard.ps1 -TenantUrl "https://contoso.sharepoint.com" `
    -ClientId "your-app-id" `
    -CertificatePath ".\cert.pfx" `
    -CertificatePassword $securePass `
    -Tenant "contoso.onmicrosoft.com"
```

### STEP 2: Create UCC Sites (repeat for each site)

```powershell
.\UCC.Site.Creator.ps1 `
    -paramUccName "ucc-sales" `
    -paramUccTitle "Sales UCC" `
    -paramSiteCollectionUrl "https://contoso.sharepoint.com/sites/ucc-sales" `
    -Interactive `
    -paramInteractiveClientId "your-app-id"
```

### STEP 3: Modernize Existing Sites (optional, for pre-existing sites)

```powershell
# Single site
.\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc-sales" `
    -Mode Modernize -Interactive -ClientId "your-app-id"

# Batch modernization via CSV
.\Batch-ModernizeUccSites.ps1 -InputCsv ".\UccSites.csv" -Mode Analyze `
    -ClientId "your-app-id" -CertificatePath ".\cert.pfx" `
    -Tenant "contoso.onmicrosoft.com" -CertificatePassword $securePass
```

## What's New in 8.4.1.9

See the full [What's New in 8.4.1.8 → 8.4.1.9](WhatsNew-8.4.1.8-to-8.4.1.9.md) article for details. Key changes include:

- **Sites.Selected permission model** — deploy using a restricted Entra ID app with no tenant admin involvement after initial setup, using a site collection app catalog
- **UCC Dashboard SPFx v8.4.1.9** — updated package with fixes for list filtering/sorting, IVR skill assignment, SkillsPerAgent item limit, PSTN agent validation, and more
- **List schema corrections** — EncryptedTokens, CannedResponses, Modalities, and ReservationPointSystemRules now receive their full content types and columns on new sites
- **Navigation hidden on new sites** — left navigation is now hidden immediately during provisioning, not just during modernization
- **Bug fixes** — PS7 relaunch with correct executable, site owner parameter preserved through relaunch, configuration.xml owner value parsed correctly
- **Permission snapshot/restore** — modernization captures and verifies permission state before and after changes

## Scripts Overview

| Script | Purpose | When to Use |
|--------|---------|-------------|
| `Deploy-UccDashboard.ps1` | One-time tenant setup (deploys SPFx) | Run once per customer tenant |
| `UCC.Site.Creator.ps1` | Create individual UCC sites | Run for each new UCC site |
| `Modernize-UccSite.ps1` | Modernize single existing site | Run on pre-existing UCC sites |
| `Batch-ModernizeUccSites.ps1` | Batch analyze/modernize sites | Run for bulk modernization |

## Modernize-UccSite.ps1

In-place modernization tool for existing UCC sites. Automatically detects site type and applies appropriate changes.

### Site Type Detection

| Detection | Site Type | Action |
|-----------|-----------|--------|
| Has "Agents" list | UCC Site | Creates Home.aspx with UCC Dashboard web part |
| Has "Anywhere365 UCC Creator" list, no Agents | Parent/Hub Site | Sets homepage to A365_UCC_Creator list view |

### What It Does

- Creates modern Home.aspx with UCC Dashboard SPFx web part
- Removes legacy portal.aspx and ivrgfx.aspx pages
- Removes Anywhere365 branding (ScriptLink custom actions, features, site logo)
- Hides left navigation for clean layout
- Sets minimal header layout
- Cleans up property bag entries

### Modes

```powershell
# Analyze only (no changes)
.\Modernize-UccSite.ps1 -SiteUrl "https://..." -Mode Analyze -Interactive -ClientId "your-app-id"

# Modernize
.\Modernize-UccSite.ps1 -SiteUrl "https://..." -Mode Modernize -Interactive -ClientId "your-app-id"

# Force re-modernize (even if already modern)
.\Modernize-UccSite.ps1 -SiteUrl "https://..." -Mode Modernize -Force -Interactive -ClientId "your-app-id"
```

## Batch-ModernizeUccSites.ps1

Batch tool for analyzing and modernizing multiple UCC sites from a CSV file.

### CSV Format (UccSites.csv)

```csv
SiteUrl
https://contoso.sharepoint.com/sites/ucc-parent
https://contoso.sharepoint.com/sites/ucc-parent/ucc-site-a
https://contoso.sharepoint.com/sites/ucc-parent/ucc-site-b
https://contoso.sharepoint.com/sites/ucc-standalone
```

**Important:** List parent sites before their subsites. Modernizing the parent first ensures subsites inherit clean navigation.

### Modes

The script supports three modes: **Discover**, **Analyze**, and **Modernize**. Running them in sequence is the recommended approach.

#### Mode Discover

Scans the entire tenant and automatically identifies all UCC sites by checking for the presence of the core UCC lists (`Agents`, `Skills`, `Endpoints`, `Businesshours`). This is the recommended starting point for large tenants where the full list of UCC sites is not known upfront.

> **Note:** Discover mode requires `-TenantUrl` pointing to the SharePoint **admin** URL and `Sites.FullControl.All` permission, as it needs to enumerate all site collections in the tenant.

```powershell
# Discover - find all UCC sites in the tenant (interactive)
.\Batch-ModernizeUccSites.ps1 -TenantUrl "https://contoso-admin.sharepoint.com" `
    -Mode Discover -Interactive -ClientId "your-app-id"

# Discover - certificate authentication
.\Batch-ModernizeUccSites.ps1 -TenantUrl "https://contoso-admin.sharepoint.com" `
    -Mode Discover `
    -ClientId "your-app-id" -CertificatePath ".\cert.pfx" `
    -Tenant "contoso.onmicrosoft.com" -CertificatePassword $securePass
```

Output: `Reports\UccSites-<timestamp>.csv` — use this as input for the Analyze and Modernize steps.

#### Mode Analyze

Reviews sites from a CSV file and reports their modernization status without making any changes.

```powershell
# Analyze - shows which sites need modernization
.\Batch-ModernizeUccSites.ps1 -InputCsv ".\UccSites.csv" -Mode Analyze `
    -ClientId "your-app-id" -CertificatePath ".\cert.pfx" `
    -Tenant "contoso.onmicrosoft.com" -CertificatePassword $securePass
```

#### Mode Modernize

Applies modernization to all sites in the CSV. Always run Analyze first to review what will be changed.

```powershell
# Modernize - applies changes to all sites
.\Batch-ModernizeUccSites.ps1 -InputCsv ".\UccSites.csv" -Mode Modernize `
    -ClientId "your-app-id" -CertificatePath ".\cert.pfx" `
    -Tenant "contoso.onmicrosoft.com" -CertificatePassword $securePass
```

#### Recommended Workflow

```
Discover  →  Analyze  →  Modernize
```

**Step 1 — Discover:** Scan the tenant and generate a site list CSV.
**Step 2 — Analyze:** Review the CSV (remove any sites to exclude), then run Analyze to check modernization status with no changes made.
**Step 3 — Modernize:** Run Modernize against the reviewed CSV to apply all changes.

### Sample Output (Analyze)

```
[INFO] Processing 4 sites...
[INFO] [1 / 4] https://contoso.sharepoint.com/sites/ucc-parent
[OK]     [Parent Site] Already modern
[INFO] [2 / 4] https://contoso.sharepoint.com/sites/ucc-parent/ucc-site-a
[OK]     [UCC Site] Already modern
[INFO] [3 / 4] https://contoso.sharepoint.com/sites/ucc-parent/ucc-site-b
[WARN]   [UCC Site] Needs modernization (27 lists, 370 items)
[INFO] [4 / 4] https://contoso.sharepoint.com/sites/ucc-standalone
[WARN]   [UCC Site] Needs modernization (27 lists, 370 items)
```

## Authentication

All three main scripts (`UCC.Site.Creator.ps1`, `Modernize-UccSite.ps1`, `Batch-ModernizeUccSites.ps1`) support the same three authentication methods:

| Method | UCC.Site.Creator.ps1 | Modernize-UccSite.ps1 | Batch-ModernizeUccSites.ps1 |
|--------|---------------------|-----------------------|-----------------------------|
| Interactive (browser login) | ✅ | ✅ | ✅ |
| Certificate (parameters) | ✅ | ✅ | ✅ |
| Certificate (configuration.xml) | ✅ | ✅ | ✅ |

### Interactive (Browser Login)

Prompts for browser-based login. Suitable for manual runs and initial setup.

```powershell
-Interactive -ClientId "your-entra-app-id"
# or for UCC.Site.Creator.ps1:
-Interactive -paramInteractiveClientId "your-entra-app-id"
```

### Certificate (Parameters)

Fully unattended authentication. Suitable for automation and CI/CD pipelines.

```powershell
-ClientId "your-entra-app-id" `
-CertificatePath ".\cert.pfx" `
-CertificatePassword $securePass `
-Tenant "contoso.onmicrosoft.com"
```

### Certificate (configuration.xml)

When `-Interactive` is not specified and certificate parameters are not passed on the command line, `Modernize-UccSite.ps1` and `Batch-ModernizeUccSites.ps1` automatically fall back to reading authentication values from `configuration.xml`. This allows the scripts to be run with minimal parameters:

```powershell
.\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc-sales" -Mode Modernize

.\Batch-ModernizeUccSites.ps1 -InputCsv ".\UccSites.csv" -Mode Analyze
```

The script will report which values it reads from `configuration.xml`:

```
Info : Reading fallback parameters from configuration.xml
Info : Using ClientId from configuration.xml
Info : Using Tenant from configuration.xml
Info : Using CertificatePath from configuration.xml
Info : Using CertificatePassword from configuration.xml
```

> **Note:** The `configuration.xml` fallback is ignored when `-Interactive` is specified.

### Entra ID App Registration Requirements

**Standard model (Sites.FullControl.All):**
- **API Permissions:** SharePoint > `Sites.FullControl.All` (Application)
- **Certificate:** Upload the .cer public key to the app registration
- **Admin Consent:** Required for the application permissions

**Restricted model (Sites.Selected):**
- **API Permissions:** SharePoint > `Sites.Selected` (Application), Microsoft Graph > `Sites.Selected` (Application)
- **Certificate:** Upload the .cer public key to the app registration
- **Admin Consent:** Required for the application permissions
- **Additional setup:** A SharePoint Administrator must grant the app access to the specific site collection and activate a site collection app catalog. See [UCC Site Collection Deployment — Sites.Selected Permission Model](UCC-SiteCollection-SitesSelected-Guide.md) for the full setup guide.

## SPFx Components

### UCC Dashboard Web Part

Modern replacement for the classic portal.aspx dashboard. Displays:
- User/Agent statistics
- Outbound Dialer status
- Recording settings
- Agents in Skill count
- Business Hours status
- Missed Calls count
- Voicemail count
- Quick navigation cards for all UCC lists

The pre-built `SPFx/ucc-dashboard-spfx.sppkg` is deployed automatically by `Deploy-UccDashboard.ps1`.

## Package Structure

```
UCC_Site_Creator_v8_4_1_9/
├── UCC.Site.Creator.ps1          # Main site creation script
├── Deploy-UccDashboard.ps1       # One-time tenant setup (deploys SPFx dashboard)
├── Modernize-UccSite.ps1         # Single-site modernization
├── Batch-ModernizeUccSites.ps1   # Batch modernization
├── SchemaUpdates.ps1             # List schema updates module
├── configuration.xml             # Site configuration
├── README.md                     # This file
├── Tools/
│   └── Migrate-UccSite.ps1       # Site migration utility (experimental)
├── AnywhereNow/
│   ├── Assets/                   # Branding and style assets
│   ├── CSV/                      # List content templates (multi-language)
│   ├── ListForms/                # Legacy webpart definitions (classic sites)
│   ├── Pages/                    # Legacy page templates
│   └── Scripts/                  # Core provisioning scripts
│       ├── Shared.ps1
│       ├── SharedPnpFunctions.ps1
│       ├── WSP.UCC-*.ps1         # Provisioning modules
│       └── Updates/
│           ├── Site/             # Site-level updates (6.0-8.3)
│           └── SiteCollection/   # Collection-level updates
├── SPFx/
│   ├── sharepoint/solution/
│   │   └── ucc-dashboard-spfx.sppkg  # Pre-built SPFx package
│   └── README.md                     # SPFx documentation
└── bundle/
    └── PnP.PowerShell/          # Bundled PnP.PowerShell v3.1.0
```


## Nested Subsites (Regional Groupings)

The modernization scripts fully support nested subsite structures commonly used for regional or country-based groupings:

```
/sites/ucc                    (site collection)
  /france                     (regional grouping - skipped if no UCC lists)
    /paris-ucc                (UCC site - will be modernized)
    /lyon-ucc                 (UCC site - will be modernized)
  /apac                       (regional grouping - skipped if no UCC lists)
    /tokyo-ucc                (UCC site - will be modernized)
```

**Key behaviors:**
- `Batch-ModernizeUccSites.ps1` with `-Mode Discover` recursively finds subsites at any depth
- Sites without UCC lists (like grouping containers) are automatically skipped
- `Modernize-UccSite.ps1` accepts any URL directly, regardless of nesting depth

**Example - Modernize a nested subsite:**
```powershell
.\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc/france/paris-ucc" -Mode Modernize -Interactive -ClientId "your-client-id"
```
## Known Limitations

- **Full-width sections on classic subsites:** Subsites created under classic site collections display the UCC Dashboard in a standard-width column rather than full-width. This is a SharePoint platform limitation. The dashboard is fully functional regardless.
- **Navigation inheritance:** Subsites inherit navigation from the parent site collection. Always modernize the parent site first when working with subsite architectures.

## Troubleshooting

### "PowerShell 7.4.6 or later is required"
Install PowerShell 7 from: https://github.com/PowerShell/PowerShell/releases

### "ClientId parameter is required"
All scripts require an Entra ID App Registration ClientId. The PnP default multi-tenant app was discontinued in September 2024.

### UCC Dashboard not appearing
- **Tenant catalog model:** Ensure `Deploy-UccDashboard.ps1` was run first to deploy the SPFx package tenant-wide.
- **Site collection catalog model:** Ensure `Deploy-UccDashboard.ps1 -SiteCollectionAppCatalogUrl` was run first. The script uploads the package, deploys client-side assets, and installs the app on all subsites.

### "The item that you are trying to delete is the current welcome page"
This is handled automatically — the script updates the existing page instead. No action needed.
