Преобразование выбранных классических страниц с помощью PnP PowerShell

Средство оценки Microsoft 365 инвентаризирует классические страницы, но не изменяет их. Используйте результаты оценки для утверждения волны страниц и используйте PnP PowerShell ConvertTo-PnPPage для создания современных страниц.

Примечание.

PnP PowerShell — это решение с открытым исходным кодом, поддержка которого предоставляется активным сообществом. Для инструментов с открытым исходным кодом не существует соглашения об уровне обслуживания в отношении поддержки корпорацией Майкрософт.

Рабочий процесс преобразования страницы

  1. Выберите репрезентативную волну страницы из завершенного покрытия оценки.
  2. Устраните блокировку веб-частей и выберите локальную или межсайтовую цель.
  3. Подготовьте приложение PnP PowerShell, принадлежащее клиенту, и необходимые разрешения.
  4. Преобразуйте репрезентативную волну с помощью значений по умолчанию с сохранением источника и ведения журнала.
  5. Проверяйте каждую сгенерированную страницу перед расширением волны.

Подготовка к работе

Выполните следующие предварительные требования:

  1. Запуск и интерпретация оценки классических страниц.
  2. Выберите репрезентативную волну из успешного покрытия сканирования.
  3. Установите PowerShell 7.4.0 или более поздней версии и текущий стабильный выпуск PnP PowerShell.
  4. Зарегистрируйте приложение Microsoft Entra, принадлежащее клиенту, для интерактивного PnP PowerShell.
  5. Убедитесь, что пользователь, вошедший в систему, может редактировать страницы на исходном и целевом веб-сайтах.

С 9 сентября 2024 г. для интерактивной проверки подлинности PnP PowerShell требуется собственная регистрация приложения и идентификатор клиента.

Учетной записи, которая регистрирует приложение, должно быть разрешено создавать регистрации приложений. Политика согласия клиента определяет, должен ли администратор предоставлять согласие.

Разрешения

Используйте отдельное делегированное приложение от приложения оценки только для чтения.

Требование к преобразованию Делегированная область действия SharePoint
Прочтите исходный код, создавайте, сохраняйте и публикуйте современную страницу AllSites.Manage
Также копирование уникальных разрешений уровня элемента AllSites.FullControl

Также применяются разрешения на доступ к сайту вошедшего пользователя. Делегированная область приложения не предоставляет пользователю доступ к сайту, к которому он не смог бы получить доступ в противном случае.

С AllSites.Manageпомощью , добавьте -SkipItemLevelPermissionCopyToClientSidePage , чтобы созданная страница унаследовала разрешения от своей библиотеки. Используйте AllSites.FullControl , только если необходимо сохранить уникальные разрешения страницы.

Установка или обновление PnP PowerShell

Для функции PnP PowerShell требуется PowerShell 7.4.0 или более поздней версии.

$PSVersionTable.PSVersion
Install-Module PnP.PowerShell -Scope CurrentUser

Если PnP PowerShell уже установлен, запустите Update-Module PnP.PowerShell PowerShell 7.4.0 или более поздней версии.

См. раздел "Установка PnP PowerShell".

Регистрация интерактивного приложения преобразования

Следующая команда создает общедоступное клиентское приложение для интерактивного входа:

Register-PnPEntraIDAppForInteractiveLogin `
  -ApplicationName "Classic Page Transformation" `
  -Tenant "<tenant>.onmicrosoft.com" `
  -SharePointDelegatePermissions AllSites.Manage `
  -SignInAudience AzureADMyOrg

Скопируйте возвращенный идентификатор приложения. В зависимости от политики согласия клиента администратору может потребоваться предоставить согласие перед первым подключением.

Регистрация общедоступного клиента предназначена для делегированного, интерактивного входа или входа на устройство. Она не предоставляет разрешения или сертификат приложения, необходимые для автоматической проверки подлинности.

Инструкции по регистрации вручную и другие методы проверки подлинности см. в разделе Регистрация приложения Entra ID для PnP PowerShell.

Для GCC High, DoD или Microsoft 365, предоставляемых 21Vianet, укажите совпадающее -AzureEnvironment значение при регистрации приложения и подключении. См. справочники по командлетам Register-PnPEntraIDAppForInteractiveLogin и Connect-PnPOnline .

Сопоставление строки оценки с PnP PowerShell

Поле оценки Использование PnP PowerShell
SiteUrl + WebUrl Исходный URL-адрес для Connect-PnPOnline.
ListUrl, ListId, PageUrl Точное SitePages удостоверение библиотеки и исходного файла.
PageType Должно быть WikiPage или WebPartPage для этого рабочего процесса.
Layout Группирование и проверка репрезентативных шаблонов.

Перед преобразованием страницы первой волны требуйте:

  • Успешное освещение сайта и веб-сайтов.
  • PageType WikiPage равно или WebPartPage.
  • Нет неразрешенных несопоставленных веб-частей.
  • WebPartCount больше 0. Обработка страниц с нулевыми частями за пределами этого автоматизированного примера после ручной проверки.
  • Исходная страница, наследующая разрешения от своей библиотеки.
  • Записанное содержимое и базовый план макета для проверки.

Создание репрезентативных групп страниц

Следующий сценарий создает инвентарь-кандидат. Он не преобразует страницы.

Он группирует подходящие страницы вики- и веб-частей по типу страницы, макету и заказанной подписи веб-части. Подпись включает тип веб-части, результат сопоставления, скрытое и закрытое состояние.

$pages = Import-Csv .\classicpages.csv
$webParts = Import-Csv .\classicpagewebparts.csv
$partsByPage = @{}

function Get-PageKey {
  param($Row)

  '{0}|{1}|{2}|{3}' -f $Row.ScanId, $Row.SiteUrl, $Row.WebUrl, $Row.PageUrl
}

foreach ($part in $webParts) {
  $key = Get-PageKey $part
  if (-not $partsByPage.ContainsKey($key)) {
    $partsByPage[$key] = [Collections.Generic.List[object]]::new()
  }

  $partsByPage[$key].Add($part)
}

$candidates = foreach ($page in $pages) {
  $fileName = [IO.Path]::GetFileName($page.PageUrl)

  if ($page.PageType -notin @('WikiPage', 'WebPartPage') -or
      $page.HomePage -eq 'True' -or
      -not $page.ListUrl.EndsWith('/SitePages', [StringComparison]::OrdinalIgnoreCase) -or
      $page.WebPartCount -eq '0' -or
      $page.MappingPercentage -ne '100' -or
      -not [string]::IsNullOrWhiteSpace($page.UnmappedWebParts) -or
      $fileName.StartsWith('Migrated_', [StringComparison]::OrdinalIgnoreCase) -or
      $fileName.StartsWith('Previous_', [StringComparison]::OrdinalIgnoreCase)) {
    continue
  }

  $key = Get-PageKey $page
  if (-not $partsByPage.ContainsKey($key)) {
    throw "Web Part rows are missing for $($page.PageUrl)."
  }

  $signature = (
    $partsByPage[$key] |
      Sort-Object { [int]$_.WebPartIndex } |
      ForEach-Object {
        '{0}|Mappable={1}|Hidden={2}|Closed={3}' -f
          $_.WebPartTypeShort, $_.IsMappable, $_.Hidden, $_.IsClosed
      }
  ) -join ';'

  [pscustomobject]@{
    PatternKey = '{0}|{1}|{2}' -f $page.PageType, $page.Layout, $signature
    ScanId = $page.ScanId
    SiteUrl = $page.SiteUrl
    WebUrl = $page.WebUrl
    PageUrl = $page.PageUrl
    PageType = $page.PageType
    ListUrl = $page.ListUrl
    ListId = $page.ListId
    AssessmentTimeZoneId = [TimeZoneInfo]::Local.Id
    Layout = $page.Layout
    HomePage = $page.HomePage
    WebPartCount = [int]$page.WebPartCount
    MappingPercentage = $page.MappingPercentage
    UnmappedWebParts = $page.UnmappedWebParts
    ModifiedAt = $page.ModifiedAt
    WebPartSignature = $signature
    IncludePattern = 'True'
    Selected = 'False'
    ExpectedVisibleContent = ''
    ValidationOwner = ''
  }
}

$groups = $candidates | Group-Object PatternKey -AsHashTable -AsString

$candidateInventory = foreach ($candidate in $candidates) {
  $candidate | Select-Object *,
    @{ Name = 'PatternPageCount'; Expression = { $groups[$candidate.PatternKey].Count } }
}

$candidateInventory |
  Sort-Object PatternKey, PageUrl |
  Export-Csv .\representative-page-groups.csv -NoTypeInformation

Просмотрите representative-page-groups.csv и выберите хотя бы одну страницу из каждой PatternKey , которая будет содержаться в волне миграции. Выбирайте дополнительные страницы, если свойства веб-части, связанный контент или бизнес-поведение существенно различаются в рамках шаблона.

Установите IncludePattern=False шаблоны за пределами плановой миграции. Для каждой выделенной страницы задайте Selected=True и заполните ExpectedVisibleContent и ValidationOwner.

Выполните шаг группировки на том же компьютере, на котором были созданы CSV-файлы оценки. AssessmentTimeZoneId Записывает часовой пояс, используемый для интерпретации значения без ModifiedAt смещения.

Храните нулевые страницы, домашние страницы, страницы публикации и страницы с неразрешенными сопоставлениями в отдельных очередях проверки. Страницы за пределами библиотеки по умолчанию SitePages также остаются в отдельно проверенном одностраничном пути.

Общие сведения о параметрах по умолчанию с сохранением источника

Предостережение

-TakeSourcePageName Переименование классической исходной страницы и -Overwrite замена существующей целевой страницы. Не используйте ни один из вариантов, пока созданные страницы не будут утверждены и не будет разработан план отката.

Вариант Руководство для первой волны
Присвоение имен по умолчанию Сохраните имя источника и создайте Migrated_<source-page>.aspxфайл
-TakeSourcePageName Не используйте изначально. Он переименовывает классический источник с приставкой Previous_ .
-Overwrite Не используйте изначально. Проверяйте существующий целевой объект вместо его автоматической замены.
-ReplaceHomePageWithDefault Не используйте в репрезентативной волне.
-DontPublish Используйте для первой волны, чтобы сгенерированная страница оставалась черновиком во время проверки.
-SkipItemLevelPermissionCopyToClientSidePage Использовать с приложением AllSites.Manage , если не нужно копировать уникальные разрешения.

Откат черновика первой волны

Пакетный рабочий процесс не переименовывает и не перезаписывает классическую исходную страницу. Если созданный черновик не прошел проверку:

  1. Оставьте классическую исходную страницу в службе.
  2. Keep TransformationStatus=Created, set ValidationStatus=Failed, and fill , ValidatedBy, and ValidatedAt.ValidationNotes
  3. Сохранить TargetPageUrl и LogPath с доказательством неудачной проверки.
  4. Перерабатывайте созданный Migrated_ черновик из библиотеки страниц сайта , когда он больше не нужен для исследования и политика хранения организации разрешает удаление.
  5. Исправьте правило-кандидат или исправление и повторите попытку создания одной репрезентативной страницы перед возобновлением волны.

-Overwrite и -TakeSourcePageName находятся вне пакетного рабочего процесса. Прежде чем использовать любой из вариантов в отдельной процедуре, сохраните версии и URL-адреса страниц, запишите текущий параметр домашней страницы, проверьте процесс обратного переименования или восстановления на нерабочем сайте и получите явное утверждение.

Преобразование одной выбранной вики-страницы или веб-части

Используйте сценарий представительной страницы с одной строкой, отмеченной Selected=True. Это сохраняет одностраничный тест на той же проверке, аутентификации и контракте результата, что и более крупная волна.

Пакетные сценарии поддерживают вики-страницы и веб-части в библиотеке по умолчанию SitePages . Они не включают домашние страницы, страницы без частей, страницы с уникальными разрешениями и страницы, измененные после оценки. Обрабатывать эти страницы можно по отдельному проверенному пути.

Преобразование всех репрезентативных страниц

Сохраните три внедренных файла из справочника по сценарию волны страницы в одной папке.

В representative-page-groups.csv:

  1. Задайте IncludePattern=True для каждого шаблона преобразования в запланированной миграции.
  2. Задайте Selected=True хотя бы на одной странице в каждом включенном шаблоне.
  3. Заполните ExpectedVisibleContent и ValidationOwner для каждой выбранной страницы.

Просмотрите всю волну без проверки подлинности или написания страниц SharePoint:

.\Convert-RepresentativePages.ps1 `
  -ManifestPath .\representative-page-groups.csv `
  -ClientId "<application-id>" `
  -AuthenticationMode Interactive `
  -WhatIf `
  -Force

Предварительный просмотр записей PlannedAction CSV и PlannedTargetPageUrl. Потому что -WhatIf не проходит проверку подлинности, TargetExists есть NotChecked.

Запустите прошедший с проверкой подлинности предварительный тест только для чтения, чтобы проверить текущий источник, домашнюю страницу, разрешения, метки времени и целевое отсутствие:

.\Convert-RepresentativePages.ps1 `
  -ManifestPath .\representative-page-groups.csv `
  -ClientId "<application-id>" `
  -AuthenticationMode Interactive `
  -PreflightOnly `
  -Confirm:$false `
  -Force

Каждая строка должна сообщить перед TransformationStatus=PreflightPassed динамическим преобразованием.

Интерактивный запуск с подтверждением важных событий:

.\Convert-RepresentativePages.ps1 `
  -ManifestPath .\representative-page-groups.csv `
  -ClientId "<application-id>" `
  -AuthenticationMode Interactive `
  -Confirm

Сценарий записывает каждый результат сразу в representative-page-results.csv. Созданные страницы остаются черновиками, и каждая созданная строка начинается с ValidationStatus=Pending.

Подписка Проверка преобразованных классических страниц. Установите ValidationStatus=Passedзначение , ValidationNotes, ValidatedBy, и ValidatedAt только после того, как страница соответствует всем критериям приемлемости.

Развернуть до всех указанных пользователем страниц

Создайте approved-pages.csv создание, скопировав дополнительные включенные строки, утвержденные пользователем, из исходного representative-page-groups.csvфайла. Сохранить каждое созданное поле, а также заполнить ExpectedVisibleContent и ValidationOwner.

Запустите сценарий на выбранной странице с помощью -PreflightOnly -Confirm:$false -Force first. Каждая строка должна сообщать PreflightPassed.

Запустите сценарий расширения:

.\Convert-SelectedPages.ps1 `
  -PagesPath .\approved-pages.csv `
  -RepresentativeManifestPath .\representative-page-groups.csv `
  -RepresentativeResultsPath .\representative-page-results.csv `
  -ClientId "<application-id>" `
  -AuthenticationMode Interactive `
  -Confirm

Сценарий отказывается расширяться в следующих случаях:

  • Репрезентативный манифест и результаты не совпадают.
  • Любая репрезентативная страница не Created и Passed.
  • Отсутствуют заметки о валидации, валидатор или метка времени проверки.
  • Версия PnP PowerShell или любой из трех файлов сценариев отличается от показательного запуска.
  • Утвержденная страница — это не неизменная включенная строка из исходного манифеста.
  • Утвержденная страница относится к шаблону без проходного представителя.

Расширенная волна также создает черновые страницы и пишет selected-page-results.csv. Проверьте эти страницы перед публикацией.

Параметры, требующие явной проверки

Используйте созданный справочник по командлетам ConvertTo-PnPPage для полного контракта параметров.

Пакетные сценарии не поддерживают пользовательские сопоставления веб-частей, страницы публикации или межсайтовые цели. Обрабатывайте эти сценарии с помощью отдельно проверенной одностраничной или расширенной процедуры.

Проверяйте эти параметры только за пределами пакетного рабочего процесса:

  • -CopyPageMetadata и -KeepPageCreationModificationInformation.
  • -UrlMappingFile, -UserMappingFile, и -TermMappingFile.
  • -Overwrite а -TakeSourcePageName также после утверждения и планирования отката.

Устранение неполадок с возможностью создания современной страницы

Сценарии волны страниц не включают функции SharePoint. Этот способ устранения неполадок применим только к поддерживаемому классическому сайту группы. Не включайте эту функцию на классическом портале публикации. Маршрутизация страниц публикации в отдельный список невыполненной работы и модель публикации на нескольких сайтах. См. раздел "Поддерживаемые настройки современных страниц".

Подключитесь к учетной записи, авторизованной для управления веб-службой, и перечислите активированные веб-функции:

$source = Connect-PnPOnline `
  -Url "https://<tenant>.sharepoint.com/sites/<site>" `
  -Interactive `
  -ClientId "<application-id>" `
  -ReturnConnection

$modernPageFeatureId = [guid]'B6917CB1-93A0-4B97-A84D-7CF49975D4EC'
$modernPageFeature = Get-PnPFeature `
  -Scope Web `
  -Connection $source |
  Where-Object DefinitionId -eq $modernPageFeatureId

if ($modernPageFeature) {
  Write-Host "Modern pages feature is active."
}
else {
  Write-Host "Modern pages feature is not active."
}

Делегированного AllSites.Manage приложения, используемого пакетными сценариями, недостаточно для активации веб-функций. Если функция не активна на поддерживаемом классическом сайте группы, получите утверждение владельца сайта и свяжитесь с:

  • Отдельное делегированное приложение с SharePoint AllSites.FullControl.
  • Учетная запись для входа с полным доступом в Интернете.
$adminConnection = Connect-PnPOnline `
  -Url "https://<tenant>.sharepoint.com/sites/<site>" `
  -Interactive `
  -ClientId "<full-control-application-id>" `
  -ReturnConnection

Enable-PnPFeature `
  -Identity $modernPageFeatureId `
  -Scope Web `
  -Connection $adminConnection

Повторно запустите прошедший проверку подлинности предварительный тест после включения функции.

Автоматическая проверка подлинности и другие типы страниц

Делегированное приложение общедоступного клиента, созданное ранее, невозможно повторно использовать для проверки подлинности только приложения на основе сертификата, если оно не настроено отдельно для доступа только к приложениям.

Перед автоматическим выполнением:

  1. Создайте отдельную регистрацию и сертификат только для приложений, следуя инструкциям Зарегистрируйте приложение Entra ID для доступа только к приложению.
  2. Настройте разрешения приложений SharePoint или назначения сайтов для каждого исходного сайта, следуя инструкциям Определение необходимых разрешений PnP PowerShell.
  3. Предоставьте необходимое согласие администратора.
  4. Запустите пакетный сценарий с -PreflightOnly -Confirm:$false режимом проверки подлинности сертификата.
  5. Удаляйте -PreflightOnly данные только после прохождения проверки подлинности в тестовом клиенте.

Важно!

Пути к параметрам сертификата тестируются Pester, но в живом клиенте уровня 2 выполняется проверенная делегированная интерактивная проверка подлинности. Проверяйте выбранный профиль разрешений только для приложений в клиенте перед автоматической записью.

Страницы публикации, страницы блогов, внешние страницы SitePages, домашние страницы, сопоставления веб-частей и исходные коды SharePoint Server не поддерживаются пакетными сценариями. Используйте эти расширенные ссылки:

Дальнейшие действия

  1. Проверьте каждую преобразованную страницу.
  2. Запускать Convert-SelectedPages.ps1 только после того, как каждая репрезентативная страница пройдет проверку.

Справочные материалы