SobreCompetênciasTrabalhoR&DBlogFerramentasComeçarContacto

Migrar o SharePoint 2016 e 2019 para a Subscription Edition: os scripts

O SharePoint 2016 vai direto para a Subscription Edition. Não há salto pelo 2019, o método é database attach e mais nenhum, e a ordem das service applications não é uma preferência. A sequência toda em PowerShell, do inventário que se tira antes de mexer em nada ao crawl que se corre no fim.

pH7x Systems® · · 18 min de leitura

O suporte do SharePoint Server 2016 e 2019 acaba a 14 de julho de 2026, e o único destino on-premises suportado é a Subscription Edition. Este artigo é a sequência, em PowerShell, com as partes que bloqueiam uma migração assinaladas onde elas mordem de facto.

Uma coisa antes do código, porque muda o plano e o orçamento.

O SharePoint 2016 vai direto para a Subscription Edition

A crença mais cara deste projeto é a de que é preciso passar primeiro pelo 2019. Não é.

"A SharePoint Server Subscription Edition suporta atualização de versão para versão N - 1 e N - 2. Pode atualizar diretamente a partir dos seguintes produtos SharePoint usando o procedimento normal de database attach: SharePoint Server 2019 (incluindo Project Server 2019), SharePoint Server 2016 (incluindo Project Server 2016)."

Um salto, a partir de qualquer um dos dois. O salto duplo só é obrigatório abaixo do 2016:

"Não é suportado atualizar diretamente por database attach a partir de versões do SharePoint anteriores ao SharePoint Server 2016. O SharePoint 2013, o SharePoint 2010 e assim por diante têm de ser primeiro atualizados para SharePoint Server 2016 ou SharePoint Server 2019 por database attach, antes de atualizar para a SharePoint Server Subscription Edition."

Percursos de atualização para a Subscription Edition. O SharePoint Server 2016 e o SharePoint Server 2019 atualizam ambos diretamente para a Subscription Edition, num único salto por database attach. O SharePoint 2013 e anteriores têm de ser primeiro atualizados para 2016 ou 2019, e só depois para a Subscription Edition. A versão mínima de base de dados aceite é 16.0.4351.1000, que é a build RTM do SharePoint Server 2016

E há um piso por baixo de tudo isto:

"Todas as bases de dados têm de estar atualizadas para a versão 16.0.4351.1000 ou superior, caso contrário a atualização para a SharePoint Server Subscription Edition será bloqueada."

Esse número é a build RTM do SharePoint Server 2016. Uma base de dados que nasceu no 2016 passa por definição. A que é recusada é a que veio do 2013, foi anexada a uma farm 2016 e nunca chegou a acabar a viagem.

O método decide o plano

Não há atualização no lugar. O único caminho suportado é o database attach, ou seja, constrói-se uma segunda farm e move-se conteúdo para lá. A configuração não viaja: web applications, service applications, políticas e definições reconstroem-se à mão na farm nova. Isso não é uma limitação a contornar, é a forma do projeto.

As quatro fases de uma atualização por database attach para a Subscription Edition, e a restrição de ordem dentro da fase três. A fase um cria a farm de Subscription Edition. A fase dois copia as bases de dados. A fase três atualiza as service applications, onde o Managed Metadata e o User Profile têm ambos de ser atualizados antes do Search, e ambos antes de qualquer My Site. A fase quatro testa e monta as bases de dados de conteúdo. As site collections atualizam-se depois automaticamente

Tudo o que se segue assume a SharePoint Management Shell aberta como administrador elevado, com a conta a ter db_owner em todas as bases de dados a atualizar, securityadmin na instância SQL, pertença ao grupo de Administradores local, e os direitos dados pelo Add-SPShellAdmin.

Nenhum dos scripts abaixo foi corrido contra uma farm. Não temos nenhuma. Cada cmdlet e cada parâmetro vem da documentação da Microsoft, mas a sequência inteira nunca foi executada, portanto trate-a como um plano para ensaiar e não como um script para colar em produção. A secção do ensaio, no fim, não é um conselho opcional.

Fase 0: o inventário, tirado antes de alguma coisa se mexer

A farm nova tem de conseguir responder por tudo o que a velha tinha. Tire o inventário primeiro, guarde-o no controlo de versões, e compare com ele no fim. Isto corre na farm velha.

powershell
# INVENTORY.PS1: runs on the SharePoint 2016 or 2019 farm.
# Reads only. Produces the record that the new farm gets compared against.
$out = "C:\Migration\inventory"
New-Item -ItemType Directory -Path $out -Force | Out-Null

# Patch level of every SharePoint product in the farm. This is the documented
# way to see what is actually installed, server by server.
Get-SPProduct |
  Select-Object ProductName, @{n='Patches';e={ $_.PatchableUnitDisplayNames -join '; ' }} |
  Export-Csv "$out\products.csv" -NoTypeInformation -Encoding UTF8

# Web applications with their URLs and authentication. The new farm has to
# reproduce these URLs exactly, or every link inside the content breaks.
Get-SPWebApplication -IncludeCentralAdministration |
  Select-Object DisplayName, Url,
    @{n='Zones';e={ ($_.AlternateUrls | ForEach-Object { "$($_.UrlZone)=$($_.IncomingUrl)" }) -join ' | ' }},
    @{n='ClaimsMode';e={ $_.UseClaimsAuthentication }} |
  Export-Csv "$out\webapps.csv" -NoTypeInformation -Encoding UTF8

# Content databases, their sizes and how many site collections each holds.
# The counts are what tells you which mount will take twenty minutes and
# which will take six hours.
Get-SPContentDatabase |
  Select-Object Name, Server, WebApplication, CurrentSiteCount,
    @{n='SizeGB';e={ [math]::Round($_.DiskSizeRequired / 1GB, 2) }} |
  Export-Csv "$out\contentdbs.csv" -NoTypeInformation -Encoding UTF8

# Farm solutions. These have to be deployed to the new farm BEFORE the content
# databases are tested, and this list is what you deploy.
Get-SPSolution |
  Select-Object Name, Deployed, ContainsGlobalAssembly, ContainsWebApplicationResource,
    @{n='DeployedTo';e={ ($_.DeployedWebApplications | ForEach-Object { $_.Url }) -join ' | ' }} |
  Export-Csv "$out\solutions.csv" -NoTypeInformation -Encoding UTF8

# Service applications and their databases. Five of these can be upgraded.
# Everything else on this list is a rebuild, and it is better to know now.
Get-SPServiceApplication |
  Select-Object DisplayName, TypeName, Status |
  Export-Csv "$out\serviceapps.csv" -NoTypeInformation -Encoding UTF8

Get-SPDatabase |
  Select-Object Name, Type, Server,
    @{n='SizeGB';e={ [math]::Round($_.DiskSizeRequired / 1GB, 2) }} |
  Export-Csv "$out\databases.csv" -NoTypeInformation -Encoding UTF8

# Every site collection, with its template. The templates are what a missing
# feature shows up as later, so this is the list you check against.
Get-SPSite -Limit All |
  Select-Object Url, @{n='Template';e={ $_.RootWeb.WebTemplate + '#' + $_.RootWeb.Configuration }},
    ContentDatabase, Owner |
  Export-Csv "$out\sites.csv" -NoTypeInformation -Encoding UTF8

Write-Host "Inventory written to $out" -ForegroundColor Green

Dois desses ficheiros ganham o lugar imediatamente. O solutions.csv passa a ser a fase 2, e o webapps.csv passa a ser a fase 1, porque os URL da farm nova têm de bater certo com os antigos, carácter a carácter.

Fase 1: a farm que recebe

Construa a farm de Subscription Edition e recrie depois as web applications. Uma decisão a tomar de propósito: se tenciona atualizar as bases de dados das service applications, não use o Farm Configuration Wizard para as criar. O assistente cria-as vazias, e uma service application de Managed Metadata vazia não é coisa que se aponte depois à sua base de dados antiga.

Certificados primeiro, porque a Subscription Edition trata deles dentro da farm e uma web application pode receber um logo na criação.

powershell
# CERTIFICATES. Subscription Edition deploys imported certificates to the
# Windows certificate store on every server in the farm automatically, and
# to any server that joins later.
$pfxPassword = Read-Host -AsSecureString -Prompt 'PFX password'
Import-SPCertificate -Path '\\fileserver\certs\sharepoint.contoso.com.pfx' `
                     -Password $pfxPassword -Exportable

# The whole chain has to be present, not just the leaf, or SSL connections fail.
Import-SPCertificate -Path '\\fileserver\certs\issuing-ca.p7b'

# Confirm what landed, and in which store.
Get-SPCertificate | Select-Object DisplayName, Store, NotAfter, Thumbprint

# Warn earlier than the default. The health rules then chase expiry for you.
Set-SPCertificateSettings -CertificateExpirationWarningThreshold 45

Depois as web applications, a bater com o inventário.

powershell
# WEB APPLICATIONS. The URL must match the old farm exactly: it is written
# into links, into search results and into anything anyone ever bookmarked.
$appPoolAccount = Get-SPManagedAccount 'CONTOSO\svc-sp-content'

# Windows claims. Classic mode was REMOVED for content web applications in
# Subscription Edition, so a farm that was still classic changes here, not later.
$ap = New-SPAuthenticationProvider

New-SPWebApplication -Name 'Contoso Intranet' `
    -ApplicationPool 'ContosoIntranetPool' `
    -ApplicationPoolAccount $appPoolAccount `
    -AuthenticationProvider $ap `
    -Port 443 -SecureSocketsLayer `
    -HostHeader 'sharepoint.contoso.com' `
    -Url 'https://sharepoint.contoso.com' `
    -Certificate 'sharepoint.contoso.com' `
    -UseServerNameIndication `
    -DatabaseName 'SP_Content_Placeholder'

# Server Name Indication is what lets several web applications share port 443
# with their own certificates. Without it they all share one certificate.

A base de dados de reserva é deliberada: a web application precisa de uma para existir, e as bases de conteúdo verdadeiras chegam na fase 4. Apague-a depois, quando as verdadeiras estiverem montadas.

Uma armadilha que custa uma paragem de serviço. Se mais tarde alterar bindings com o Set-SPWebApplication, indique-os todos outra vez:

"Todas as definições de binding do IIS devem ser reindicadas ao atualizar o binding de um site IIS através do cmdlet Set-SPWebApplication. Isto inclui o URL, a definição de secure sockets layer, o número da porta, o host header e o certificado. Se uma definição de binding não for reindicada, volta ao seu valor por omissão."

powershell
# Right: every binding setting stated, even the ones that are not changing.
Set-SPWebApplication -Identity 'https://sharepoint.contoso.com' -Zone Default `
    -Port 443 -SecureSocketsLayer `
    -HostHeader 'sharepoint.contoso.com' `
    -Url 'https://sharepoint.contoso.com' `
    -Certificate 'sharepoint.contoso.com' `
    -UseServerNameIndication

Fase 2: as personalizações vão antes do conteúdo

Esta é a inversão de ordem que produz a sessão de diagnóstico mais longa e menos útil do projeto. O Test-SPContentDatabase reporta todas as features, templates e assemblies que o conteúdo referencia e não encontra. Corra-o antes de as soluções estarem instaladas e recebe um relatório com centenas de entradas que são todas o mesmo problema.

A Microsoft aponta-o como a causa comum:

"Uma causa frequente de falhas durante a atualização é o ambiente não ter as features, soluções ou outros elementos personalizados."

powershell
# SOLUTIONS. Driven from solutions.csv, produced by the inventory.
$wsps = Import-Csv 'C:\Migration\inventory\solutions.csv'

foreach ($w in $wsps) {
    $path = Join-Path 'C:\Migration\wsp' $w.Name
    if (-not (Test-Path $path)) {
        Write-Warning "MISSING: $($w.Name). Find the package, or the sites that use it will not upgrade cleanly"
        continue
    }

    $solution = Add-SPSolution -LiteralPath $path

    # GACDeployment is required when the package contains a global assembly.
    # The inventory recorded that per solution, so it is not a guess.
    $gac = [bool]::Parse($w.ContainsGlobalAssembly)

    if ($w.ContainsWebApplicationResource -eq 'True') {
        Install-SPSolution -Identity $solution -AllWebApplications `
                           -GACDeployment:$gac -Force
    } else {
        Install-SPSolution -Identity $solution -GACDeployment:$gac -Force
    }
}

# Deployment is asynchronous: it runs on a timer job. Wait for it, or the
# next phase tests against a farm that is still deploying.
do {
    Start-Sleep -Seconds 15
    $pending = Get-SPSolution | Where-Object { $_.JobExists }
    Write-Host "Waiting for $($pending.Count) solution job(s)..."
} while ($pending)

Get-SPSolution | Select-Object Name, Deployed, DeploymentState | Format-Table -AutoSize

O que ficar na lista dos que faltam é uma decisão, não um aviso. Ou o pacote se encontra e se reconstrói, ou os sites que dependem dele são inventariados e tratados antes da migração, e não durante.

Fase 3: congelar, copiar, descongelar

A farm velha fica só de leitura em vez de ir abaixo, para as pessoas continuarem a ler enquanto a cópia corre. Isto é T-SQL, na instância de origem.

sql
-- ON THE OLD FARM'S SQL INSTANCE.
-- Read-only, not offline: people keep reading during the copy window.
ALTER DATABASE [WSS_Content_Intranet] SET READ_ONLY WITH ROLLBACK IMMEDIATE;

-- COPY_ONLY leaves the existing backup chain intact. Without it, this backup
-- becomes part of the chain and the scheduled restore plan quietly changes.
-- CHECKSUM makes the restore refuse a backup that was damaged in transit.
BACKUP DATABASE [WSS_Content_Intranet]
    TO DISK = N'\\fileserver\migration\WSS_Content_Intranet.bak'
    WITH COPY_ONLY, COMPRESSION, CHECKSUM, STATS = 5;
sql
-- ON THE SUBSCRIPTION EDITION FARM'S SQL INSTANCE.
RESTORE DATABASE [WSS_Content_Intranet]
    FROM DISK = N'\\fileserver\migration\WSS_Content_Intranet.bak'
    WITH MOVE 'WSS_Content_Intranet'     TO N'E:\SQLData\WSS_Content_Intranet.mdf',
         MOVE 'WSS_Content_Intranet_log' TO N'F:\SQLLogs\WSS_Content_Intranet_log.ldf',
         REPLACE, STATS = 5;

-- A restored copy inherits the read-only state, and a read-only database
-- cannot be attached. This is the step people forget, and Mount fails on it.
ALTER DATABASE [WSS_Content_Intranet] SET READ_WRITE WITH ROLLBACK IMMEDIATE;

As mesmas três instruções aplicam-se às bases de dados das service applications, com uma exceção tratada na fase seguinte: a base de administração do Search é copiada mais tarde, e só depois de o Search ter sido suspenso.

Fase 4: as service applications, pela ordem que não é uma preferência

Cinco bases de dados de service applications podem ser atualizadas: Business Data Connectivity, Managed Metadata, Secure Store, User Profile e Search. Tudo o resto é reconfigurado à mão, e duas são explicitamente recusadas:

"O Word Automation Services e o Machine Translation Services não podem ser atualizados. É preciso criar uma nova instância do serviço."

A ordem está fixada pelas dependências. O Managed Metadata e o User Profile vêm ambos antes do Search, e ambos antes de qualquer My Site.

powershell
# SERVICE APPLICATIONS. Order matters: MMS and UPA before Search.
$applicationPool = Get-SPServiceApplicationPool -Identity 'SharePoint Web Services default'

# --- Secure Store -------------------------------------------------------
# The passphrase is from the OLD farm. Without it the stored credentials are
# unreadable, and no amount of restoring gets them back.
$sss  = New-SPSecureStoreServiceApplication -Name 'Secure Store' `
            -ApplicationPool $applicationPool `
            -DatabaseName 'Secure_Store_Service_DB' -AuditingEnabled
$sssp = New-SPSecureStoreServiceApplicationProxy -Name 'Secure Store Proxy' `
            -ServiceApplication $sss -DefaultProxyGroup

$oldPassphrase = Read-Host -Prompt 'Secure Store passphrase from the old farm'
Update-SPSecureStoreApplicationServerKey -Passphrase $oldPassphrase `
            -ServiceApplicationProxy $sssp

# --- Business Data Connectivity ----------------------------------------
# The only one that creates its own proxy and puts it in the default group.
New-SPBusinessDataCatalogServiceApplication -Name 'BDC Service' `
    -ApplicationPool $applicationPool -DatabaseName 'BDC_Service_DB'

# --- Managed Metadata ---------------------------------------------------
$mms = New-SPMetadataServiceApplication -Name 'Managed Metadata Service' `
           -ApplicationPool $applicationPool `
           -DatabaseName 'Managed_Metadata_Service_DB'
New-SPMetadataServiceApplicationProxy -Name 'Managed Metadata Proxy' `
    -ServiceApplication $mms -DefaultProxyGroup

# --- User Profile -------------------------------------------------------
# After Managed Metadata, and before any My Site is touched. The Sync
# database is NEW: only Profile and Social come across.
New-SPProfileServiceApplication -Name 'User Profile Service Application' `
    -ApplicationPool $applicationPool `
    -ProfileDBName 'UPA_ProfileDB' `
    -SocialDBName  'UPA_SocialDB' `
    -ProfileSyncDBName 'UPA_SyncDB'

$upa = Get-SPServiceApplication | Where-Object { $_.TypeName -eq 'User Profile Service Application' }
New-SPProfileServiceApplicationProxy -Name 'User Profile Proxy' -ServiceApplication $upa

$upaProxy = Get-SPServiceApplicationProxy |
            Where-Object { $_.TypeName -eq 'User Profile Service Application Proxy' }
Add-SPServiceApplicationProxyGroupMember -member $upaProxy -identity ''

O Search é o último, e tem um passo que corre na farm velha a meio dele.

powershell
# --- Search, part one: ON THE OLD FARM ---------------------------------
# The Search Administration database is copied later than the others, because
# Search has to be paused first. While it is paused the old index stops
# updating, so results on the old farm get staler during the window.
$ssaOld = Get-SPEnterpriseSearchServiceApplication 'Search Service Application'
Suspend-SPEnterpriseSearchServiceApplication -Identity $ssaOld
# Now set the Search Admin DB read-only, back it up and restore it, as in phase 3.
powershell
# --- Search, part two: ON THE SUBSCRIPTION EDITION FARM ----------------
# The Search service instance cannot be started from Central Administration
# until a Search service application exists, so PowerShell it is.
$searchInst = Get-SPEnterpriseSearchServiceInstance -local
Start-SPServiceInstance $searchInst

# Restore, not New: this is what upgrades the admin database instead of
# creating an empty one. It keeps the search schema, the result sources and
# the query rules. It does NOT keep the index.
Restore-SPEnterpriseSearchServiceApplication `
    -Name 'Search Service Application' `
    -applicationpool $applicationPool `
    -databasename 'Search_Service_Application_DB' `
    -databaseserver 'SQLSE01' `
    -AdminSearchServiceInstance $searchInst

$ssa  = Get-SPEnterpriseSearchServiceApplication
New-SPEnterpriseSearchServiceApplicationProxy -Name 'Search Proxy' -SearchApplication $ssa
$ssap = Get-SPEnterpriseSearchServiceApplicationProxy
Add-SPServiceApplicationProxyGroupMember -member $ssap -identity ''

Se esse restore falhar, e latência de rede ou de SQL chega para o fazer falhar, a recuperação documentada não é repetir por cima: apagar a base de administração do Search meio atualizada, restaurar outra vez a cópia de segurança, pô-la em leitura e escrita, e correr o comando de novo.

Confirme depois que todos os proxies ficaram no grupo por omissão, porque uma service application que funciona mas cujo proxy não está no grupo por omissão comporta-se exatamente como uma que não existe.

powershell
$pg = Get-SPServiceApplicationProxyGroup -Identity ''
$pg.Proxies | Select-Object DisplayName, TypeName | Format-Table -AutoSize

Fase 5: testar, e só depois montar

Nunca monte primeiro. O Test-SPContentDatabase não altera nada, e é a única coisa que lhe diz o que falta enquanto ainda é barato corrigir.

Dois parâmetros ganham o lugar. O -ShowLocation diz onde é que uma feature em falta está a ser usada, o que transforma um GUID num site que tem dono. É lento, portanto pertence ao ensaio e não à corrida a sério. E o -ExtendedCheck:

"Verifica se há modos de autenticação inconsistentes durante o processo de atualização por database attach. O modo escolhido, claims ou clássico, tem de ser o mesmo nas duas versões."

Esse importa mais do que parece, porque o modo clássico foi removido para web applications de conteúdo na Subscription Edition. Uma farm que ainda corre autenticação clássica descobre-o aqui, ou descobre-o a meio de um mount.

powershell
# TEST THEN MOUNT. Driven from the inventory, one database at a time.
$dbs    = Import-Csv 'C:\Migration\inventory\contentdbs.csv'
$webApp = 'https://sharepoint.contoso.com'
$report = 'C:\Migration\reports'
New-Item -ItemType Directory -Path $report -Force | Out-Null

foreach ($db in $dbs) {

    Write-Host "`n=== $($db.Name) ===" -ForegroundColor Cyan

    # -ExtendedCheck catches a claims/classic mismatch, which Subscription
    # Edition cannot resolve later: classic mode is gone for content web apps.
    $issues = Test-SPContentDatabase -Name $db.Name -WebApplication $webApp -ExtendedCheck

    $issues | Export-Clixml "$report\$($db.Name).test.xml"
    $issues | Format-List | Out-File "$report\$($db.Name).test.txt" -Encoding UTF8

    # UpgradeBlocking is the property that separates "fix this now" from
    # "write this down". Read the file either way: a non-blocking missing
    # web part is still a broken page for whoever put it there.
    $blocking = $issues | Where-Object { $_.UpgradeBlocking }

    if ($blocking) {
        Write-Host "BLOCKED: $($blocking.Count) blocking issue(s). Not mounting." -ForegroundColor Red
        $blocking | Format-List Category, Message, Remedy
        continue
    }

    if ($issues) {
        Write-Host "$($issues.Count) non-blocking issue(s), logged. Mounting." -ForegroundColor Yellow
    }

    # Mount-SPContentDatabase, not Central Administration: attaching a database
    # through the Central Administration pages is not supported for upgrading.
    # Site collections upgrade automatically as part of this, which is the
    # default and the recommended behaviour.
    Mount-SPContentDatabase -Name $db.Name -WebApplication $webApp -Verbose

    Write-Host "MOUNTED: $($db.Name)" -ForegroundColor Green
}

Se uma base de dados tem milhares de site collections e a janela do mount é apertada, o -SkipSiteUpgrade adia a atualização dos sites para o primeiro acesso. É uma ferramenta de calendário, não um atalho: o trabalho acontece na mesma, só que espalhado e sob carga de utilizadores reais.

powershell
Mount-SPContentDatabase -Name 'WSS_Content_Archive' -WebApplication $webApp -SkipSiteUpgrade

E o modelo mudou. Já não há modos de compatibilidade:

"Não existe o conceito de 'modos de compatibilidade de site collection' na SharePoint Server Subscription Edition. Tem de estar sempre a correr a versão mais recente."

Fase 6: o que verificar antes de deixar entrar alguém

powershell
# 1. Every site collection accounted for, against the inventory.
$before = Import-Csv 'C:\Migration\inventory\sites.csv'
$after  = Get-SPSite -Limit All | Select-Object -ExpandProperty Url
$missing = $before.Url | Where-Object { $_ -notin $after }
if ($missing) { $missing | ForEach-Object { Write-Warning "MISSING SITE: $_" } }
else { Write-Host "All $($before.Count) site collections present." -ForegroundColor Green }

# 2. Site collection upgrade status, per site. The logs from Mount-based
# upgrades live inside the Upgrade*.log files, not in separate SiteUpgrade
# files, which is where people go looking and find nothing.
Get-SPSite -Limit All | ForEach-Object {
    $info = Get-SPSiteUpgradeSessionInfo -Site $_.Url -ErrorAction SilentlyContinue
    [pscustomobject]@{
        Url       = $_.Url
        Status    = $info.Status
        Errors    = $info.ErrorCount
        Warnings  = $info.WarningCount
    }
} | Where-Object { $_.Errors -gt 0 -or $_.Status -ne 'Completed' } | Format-Table -AutoSize

# 3. The index is EMPTY. The topology in the new farm is new, so a full crawl
#    over the whole corpus is mandatory, and only once every content database
#    is mounted. Starting it earlier just means crawling twice.
$ssa = Get-SPEnterpriseSearchServiceApplication
Get-SPEnterpriseSearchCrawlContentSource -SearchApplication $ssa |
  ForEach-Object { $_.StartFullCrawl() }

# 4. Which feature release ring this farm should be on. Standard is the
#    default; Early gets new experiences sooner. Record the decision.
Get-SPFeatureReleasePreference

Depois, a farm velha. Deixe-a só de leitura e a funcionar até a nova ter passado uma semana de trabalho inteira, porque o rollback mais rápido de todo este projeto é uma alteração de DNS de volta para uma farm que continua a funcionar.

Ensaie primeiro, e só depois faça

Todos os números do plano são um palpite até o ensaio os produzir. Restaure uma cópia das bases de dados de produção na farm nova, corra a sequência inteira, e aponte três coisas: quanto tempo demorou cada mount, o que é que o Test-SPContentDatabase -ShowLocation encontrou, e quais das features em falta ninguém conseguiu explicar.

Depois deite essa farm fora e faça outra vez, na janela verdadeira. A segunda corrida é a que tem tempos realistas, uma lista de soluções já completa e nenhuma surpresa no relatório de teste, porque foram todas encontradas na primeira.

Antes de começar

  • Confirme a direção: o 2016 e o 2019 vão os dois diretamente para a Subscription Edition, e só o 2013 e anteriores precisam de um salto intermédio
  • Verifique que todas as bases de dados estão em 16.0.4351.1000 ou superior, porque abaixo disso a atualização é bloqueada logo à entrada
  • Tire o inventário antes de mexer em seja o que for, e guarde-o no controlo de versões
  • Não use o Farm Configuration Wizard para as service applications cujas bases de dados tenciona atualizar
  • Reproduza exatamente os URL antigos nas web applications novas
  • Instale as farm solutions antes de correr o Test-SPContentDatabase, ou o relatório fica ilegível
  • Encontre a passphrase do Secure Store da farm antiga antes de precisar dela
  • Corra o Test-SPContentDatabase com -ExtendedCheck, e leia o relatório mesmo quando nada bloqueia
  • Ponha as bases de dados em leitura e escrita depois de restaurar, porque uma base só de leitura não pode ser montada
  • Reindique todos os bindings ao usar o Set-SPWebApplication, ou os que deixar de fora voltam ao valor por omissão
  • Planeie o full crawl, e planeie-o para depois da última base de conteúdo estar montada
  • Mantenha a farm velha só de leitura e acessível durante uma semana depois de entrar em produção

Comentários

Continuar a ler