Enhance Start-SPMigration GUI for SharePoint SSOM compatibility and update mapping schema
- Added version checks to ensure the script runs in 64-bit Windows PowerShell Desktop Edition. - Implemented checks for STA thread requirement and SharePoint environment validation. - Updated application version to 1.2.0 and supported mapping schema version to 2. - Introduced a new function to retrieve SharePoint product support information based on build version. - Modified mapping table structure to include ToolVersion and additional metadata fields. - Updated sample mapping JSON to reflect new schema version and added new fields for metadata column mappings.
This commit is contained in:
+158
-16
@@ -1,4 +1,6 @@
|
||||
|
||||
#requires -Version 5.0
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[switch]$NoGui
|
||||
@@ -6,6 +8,21 @@ param(
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
$script:ApplicationVersion = "1.2.0"
|
||||
$script:SupportedMappingSchemaVersion = 2
|
||||
|
||||
$editionProperty = $PSVersionTable.PSObject.Properties["PSEdition"]
|
||||
if ($null -ne $editionProperty -and [string]$editionProperty.Value -ne "Desktop") {
|
||||
throw "Start-SPMigration GUI muss fuer SharePoint SSOM mit Windows PowerShell (Desktop Edition), nicht mit PowerShell 7, gestartet werden."
|
||||
}
|
||||
|
||||
if (-not [Environment]::Is64BitProcess) {
|
||||
throw "Start-SPMigration GUI muss in 64-Bit Windows PowerShell gestartet werden."
|
||||
}
|
||||
|
||||
if ([System.Threading.Thread]::CurrentThread.ApartmentState -ne [System.Threading.ApartmentState]::STA) {
|
||||
throw "Start-SPMigration GUI benoetigt einen STA-Thread. Bitte mit 'powershell.exe -STA -File .\Start-SPMigrationGUI.ps1' starten."
|
||||
}
|
||||
|
||||
class SettingsManager {
|
||||
[string]$SettingsPath
|
||||
@@ -781,7 +798,7 @@ class DialogBuilder : BaseComponent {
|
||||
}
|
||||
}
|
||||
|
||||
# PowerShell 7 can fail to resolve WinForms via `using assembly`, but runtime loading works reliably.
|
||||
# WinForms and SharePoint SSOM are loaded at runtime in 64-bit Windows PowerShell.
|
||||
[void](Add-Type -AssemblyName System.Windows.Forms)
|
||||
[void](Add-Type -AssemblyName System.Drawing)
|
||||
[System.Windows.Forms.Application]::EnableVisualStyles()
|
||||
@@ -794,10 +811,14 @@ $script:MigrationScriptPath = Join-Path -Path (Split-Path -Parent $PSCommandPath
|
||||
$script:IsUpdatingContainerChecks = $false
|
||||
$script:LastSuggestedMappingPath = ""
|
||||
$script:CurrentMappingMeta = [ordered]@{
|
||||
SchemaVersion = 1
|
||||
SchemaVersion = $script:SupportedMappingSchemaVersion
|
||||
ToolVersion = $script:ApplicationVersion
|
||||
GeneratedAtUtc = ""
|
||||
SourceWebUrl = ""
|
||||
SourceSharePointProduct = ""
|
||||
SourceSharePointBuild = ""
|
||||
}
|
||||
$script:SharePointEnvironment = $null
|
||||
$script:IsMigrationRunning = $false
|
||||
$script:MigrationProcess = $null
|
||||
$script:MigrationOutputPath = ""
|
||||
@@ -844,9 +865,95 @@ function Get-ObjectPropertyValue {
|
||||
return $property.Value
|
||||
}
|
||||
|
||||
function Get-SharePointProductSupportInfo {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[version]$BuildVersion
|
||||
)
|
||||
|
||||
$productName = "Nicht unterstuetzte SharePoint-Version"
|
||||
$isSupported = $false
|
||||
|
||||
if ($BuildVersion.Major -eq 16 -and $BuildVersion.Build -ge 4351 -and $BuildVersion.Build -lt 10337) {
|
||||
$productName = "SharePoint Server 2016"
|
||||
$isSupported = $true
|
||||
}
|
||||
elseif ($BuildVersion.Major -eq 16 -and $BuildVersion.Build -ge 10337 -and $BuildVersion.Build -lt 14326) {
|
||||
$productName = "SharePoint Server 2019"
|
||||
$isSupported = $true
|
||||
}
|
||||
elseif ($BuildVersion.Major -eq 16 -and $BuildVersion.Build -ge 14326) {
|
||||
$productName = "SharePoint Server Subscription Edition"
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
ProductName = $productName
|
||||
IsSupported = $isSupported
|
||||
}
|
||||
}
|
||||
|
||||
function Initialize-SharePointPowerShellForGui {
|
||||
if ($null -eq (Get-Module -Name SharePointServer)) {
|
||||
Import-Module SharePointServer -ErrorAction Stop
|
||||
$editionProperty = $PSVersionTable.PSObject.Properties["PSEdition"]
|
||||
if ($null -ne $editionProperty -and [string]$editionProperty.Value -ne "Desktop") {
|
||||
throw "Die GUI und SharePoint SSOM werden nur unter 64-Bit Windows PowerShell (Desktop Edition), nicht unter PowerShell 7, unterstuetzt."
|
||||
}
|
||||
|
||||
if (-not [Environment]::Is64BitProcess) {
|
||||
throw "Die GUI muss fuer SharePoint SSOM in einem 64-Bit-Windows-PowerShell-Prozess ausgefuehrt werden."
|
||||
}
|
||||
|
||||
if ($PSVersionTable.PSVersion -lt [version]"5.0") {
|
||||
throw ("Die GUI erfordert Windows PowerShell 5.0 oder neuer. Gefunden: {0}" -f $PSVersionTable.PSVersion)
|
||||
}
|
||||
|
||||
if ($null -eq (Get-Command -Name Get-SPWeb -ErrorAction SilentlyContinue)) {
|
||||
$loadErrors = @()
|
||||
|
||||
try {
|
||||
Import-Module SharePointServer -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
$loadErrors += ("Import-Module SharePointServer: {0}" -f $_.Exception.Message)
|
||||
}
|
||||
|
||||
if ($null -eq (Get-Command -Name Get-SPWeb -ErrorAction SilentlyContinue)) {
|
||||
try {
|
||||
$registeredSnapIn = Get-PSSnapin -Registered -Name Microsoft.SharePoint.PowerShell -ErrorAction Stop
|
||||
if ($null -ne $registeredSnapIn -and $null -eq (Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue)) {
|
||||
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$loadErrors += ("Add-PSSnapin Microsoft.SharePoint.PowerShell: {0}" -f $_.Exception.Message)
|
||||
}
|
||||
}
|
||||
|
||||
if ($null -eq (Get-Command -Name Get-SPWeb -ErrorAction SilentlyContinue)) {
|
||||
throw ("Die SharePoint Server PowerShell-Cmdlets konnten nicht geladen werden. Die GUI muss lokal auf einem SharePoint-Server ausgefuehrt werden. {0}" -f ($loadErrors -join " | "))
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$Host.Runspace.ThreadOptions = "ReuseThread"
|
||||
}
|
||||
catch {
|
||||
}
|
||||
|
||||
$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
|
||||
if ($null -eq $farm) {
|
||||
throw "Keine lokale SharePoint-Farm gefunden. SSOM kann nur lokal auf einem SharePoint-Farmserver verwendet werden."
|
||||
}
|
||||
|
||||
$buildVersion = [version]$farm.BuildVersion
|
||||
$supportInfo = Get-SharePointProductSupportInfo -BuildVersion $buildVersion
|
||||
if (-not $supportInfo.IsSupported) {
|
||||
throw ("Nicht unterstuetzte lokale SharePoint-Farm: {0}, Build {1}. Unterstuetzt werden SharePoint Server 2016 und 2019." -f $supportInfo.ProductName, $buildVersion)
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
ProductName = $supportInfo.ProductName
|
||||
BuildVersion = $buildVersion.ToString()
|
||||
PowerShellVersion = $PSVersionTable.PSVersion.ToString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1089,12 +1196,7 @@ function Get-MigrationHostPath {
|
||||
}
|
||||
}
|
||||
|
||||
$currentProcessPath = (Get-Process -Id $PID).Path
|
||||
if (-not [string]::IsNullOrWhiteSpace($currentProcessPath) -and [System.IO.File]::Exists($currentProcessPath)) {
|
||||
return $currentProcessPath
|
||||
}
|
||||
|
||||
throw "Kein PowerShell-Host fuer die Migration gefunden."
|
||||
throw "Keine 64-Bit-Windows-PowerShell fuer die SSOM-Migration gefunden."
|
||||
}
|
||||
|
||||
function Get-SingleQuotedPowerShellLiteral {
|
||||
@@ -1414,7 +1516,7 @@ function Get-SourceContainers {
|
||||
[switch]$IncludeHiddenLists
|
||||
)
|
||||
|
||||
Initialize-SharePointPowerShellForGui
|
||||
$script:SharePointEnvironment = Initialize-SharePointPowerShellForGui
|
||||
|
||||
$web = $null
|
||||
|
||||
@@ -1996,9 +2098,12 @@ function New-EmptyMappingTable {
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
SchemaVersion = 1
|
||||
SchemaVersion = $script:SupportedMappingSchemaVersion
|
||||
ToolVersion = $script:ApplicationVersion
|
||||
GeneratedAtUtc = [System.DateTime]::UtcNow.ToString("o")
|
||||
SourceWebUrl = $sourceWebUrl
|
||||
SourceSharePointProduct = ""
|
||||
SourceSharePointBuild = ""
|
||||
LibraryMappings = @()
|
||||
ListMappings = @()
|
||||
MetadataColumnMappings = [PSCustomObject]@{
|
||||
@@ -2013,10 +2118,33 @@ function Set-MappingMetaFromObject {
|
||||
$MappingTable
|
||||
)
|
||||
|
||||
$schemaVersionValue = Get-ObjectPropertyValue -Object $MappingTable -PropertyName "SchemaVersion" -DefaultValue 1
|
||||
try {
|
||||
$schemaVersion = [int]$schemaVersionValue
|
||||
}
|
||||
catch {
|
||||
throw ("Ungueltige SchemaVersion in der MappingTable: '{0}'." -f $schemaVersionValue)
|
||||
}
|
||||
|
||||
if ($schemaVersion -lt 1) {
|
||||
throw ("Ungueltige SchemaVersion in der MappingTable: {0}." -f $schemaVersion)
|
||||
}
|
||||
|
||||
if ($schemaVersion -gt $script:SupportedMappingSchemaVersion) {
|
||||
throw ("MappingTable-SchemaVersion {0} ist neuer als die von GUI v{1} unterstuetzte Version {2}." -f $schemaVersion, $script:ApplicationVersion, $script:SupportedMappingSchemaVersion)
|
||||
}
|
||||
|
||||
if ($schemaVersion -lt $script:SupportedMappingSchemaVersion) {
|
||||
Write-UILog -Message ("MappingTable-SchemaVersion {0} wird beim Speichern auf Version {1} aktualisiert." -f $schemaVersion, $script:SupportedMappingSchemaVersion) -Level "WARN"
|
||||
}
|
||||
|
||||
$script:CurrentMappingMeta = [ordered]@{
|
||||
SchemaVersion = [int](Get-ObjectPropertyValue -Object $MappingTable -PropertyName "SchemaVersion" -DefaultValue 1)
|
||||
SchemaVersion = $script:SupportedMappingSchemaVersion
|
||||
ToolVersion = [string](Get-ObjectPropertyValue -Object $MappingTable -PropertyName "ToolVersion" -DefaultValue $script:ApplicationVersion)
|
||||
GeneratedAtUtc = [string](Get-ObjectPropertyValue -Object $MappingTable -PropertyName "GeneratedAtUtc" -DefaultValue "")
|
||||
SourceWebUrl = [string](Get-ObjectPropertyValue -Object $MappingTable -PropertyName "SourceWebUrl" -DefaultValue "")
|
||||
SourceSharePointProduct = [string](Get-ObjectPropertyValue -Object $MappingTable -PropertyName "SourceSharePointProduct" -DefaultValue "")
|
||||
SourceSharePointBuild = [string](Get-ObjectPropertyValue -Object $MappingTable -PropertyName "SourceSharePointBuild" -DefaultValue "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2057,9 +2185,12 @@ function Get-MappingTableFromUi {
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
SchemaVersion = [int]$script:CurrentMappingMeta.SchemaVersion
|
||||
SchemaVersion = $script:SupportedMappingSchemaVersion
|
||||
ToolVersion = [string]$script:CurrentMappingMeta.ToolVersion
|
||||
GeneratedAtUtc = if ([string]::IsNullOrWhiteSpace($script:CurrentMappingMeta.GeneratedAtUtc)) { [System.DateTime]::UtcNow.ToString("o") } else { $script:CurrentMappingMeta.GeneratedAtUtc }
|
||||
SourceWebUrl = $sourceWebUrl
|
||||
SourceSharePointProduct = [string]$script:CurrentMappingMeta.SourceSharePointProduct
|
||||
SourceSharePointBuild = [string]$script:CurrentMappingMeta.SourceSharePointBuild
|
||||
LibraryMappings = @(Convert-DataTableToObjects -Table $script:LibraryMappingsTable -Schema $script:GridSchemas.LibraryMappings)
|
||||
ListMappings = @(Convert-DataTableToObjects -Table $script:ListMappingsTable -Schema $script:GridSchemas.ListMappings)
|
||||
MetadataColumnMappings = [PSCustomObject]@{
|
||||
@@ -2599,7 +2730,7 @@ function Invoke-ImportFromGui {
|
||||
}
|
||||
}
|
||||
|
||||
$formBuilder = [FormBuilder]::new("Start-SPMigration GUI")
|
||||
$formBuilder = [FormBuilder]::new(("Start-SPMigration GUI v{0}" -f $script:ApplicationVersion))
|
||||
$null = $formBuilder.SetSize([int]$script:SettingsManager.Get("WindowWidth", 1400), [int]$script:SettingsManager.Get("WindowHeight", 940)).SetMinimumSize(1200, 820).SetStartPosition("CenterScreen")
|
||||
$script:MainForm = $formBuilder.Build()
|
||||
$script:MainForm.KeyPreview = $true
|
||||
@@ -3033,7 +3164,18 @@ $script:txtOutputPath.Add_TextChanged({
|
||||
})
|
||||
|
||||
$script:MainForm.Add_Shown({
|
||||
Write-UILog -Message "Start-SPMigration GUI gestartet."
|
||||
Write-UILog -Message ("Start-SPMigration GUI v{0} gestartet." -f $script:ApplicationVersion)
|
||||
try {
|
||||
$script:SharePointEnvironment = Initialize-SharePointPowerShellForGui
|
||||
Write-UILog -Message ("SSOM-Umgebung erkannt: {0}, FarmBuild={1}, WindowsPowerShell={2}" -f $script:SharePointEnvironment.ProductName, $script:SharePointEnvironment.BuildVersion, $script:SharePointEnvironment.PowerShellVersion)
|
||||
}
|
||||
catch {
|
||||
Write-UILog -Message ("SSOM-Umgebungspruefung fehlgeschlagen: {0}" -f $_.Exception.Message) -Level "ERROR"
|
||||
$btnLoadContainers.Enabled = $false
|
||||
$btnRunExport.Enabled = $false
|
||||
$btnRunImport.Enabled = $false
|
||||
Show-UiMessage -Message ("Die Migration wurde deaktiviert, weil keine unterstuetzte lokale SharePoint-2016/2019-SSOM-Umgebung erkannt wurde. Fehler: {0}" -f $_.Exception.Message) -Caption "SSOM-Umgebung nicht verfuegbar" -Icon ([System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
Load-UiSettings
|
||||
Set-MappingTableToUi -MappingTable (New-EmptyMappingTable)
|
||||
Load-ExistingMappingTableIfAvailable
|
||||
|
||||
Reference in New Issue
Block a user