Files
Start-SPMigration/README.md
Torsten Brendgen 68d7ca6755 Refactor metadata column mappings in README and PowerShell script
- Updated README to reflect changes in metadata column mappings structure, separating system and custom columns.
- Modified PowerShell script to support new metadata column mapping structure.
- Introduced functions to handle taxonomy fields and improved error handling during item saving.
- Enhanced import functionality to manage existing files and handle required fields more effectively.
2026-04-16 13:11:23 +02:00

288 lines
9.3 KiB
Markdown

# Start-SPMigration
PowerShell-Skript fuer die Migration von SharePoint On-Premise Inhalten ueber das serverseitige Objektmodell.
Das Skript kann:
- Dokumentbibliotheken exportieren
- Dateien inklusive Metadaten exportieren
- normale SharePoint-Listen und deren Eintraege exportieren
- exportierte Inhalte wieder in ein Ziel-Web importieren
- beim Export automatisch eine JSON-`MappingTable` fuer Feld-, Listen- und Bibliotheks-Mappings erzeugen
- beim Import dieselbe `MappingTable` fuer Container- und Metadaten-Mappings verwenden
## Voraussetzungen
- SharePoint On-Premise Server
- Ausfuehrung auf einem Server mit installiertem SharePoint PowerShell-Modul
- Berechtigungen auf Quell- und Ziel-Web
- PowerShell mit Zugriff auf `SharePointServer`
Das Skript laedt intern:
```powershell
Import-Module SharePointServer
```
## Dateien im Projekt
- `Start-SPMigration.ps1`: Hauptskript fuer Export und optionalen Import
- `FieldMapping.sample.csv`: altes CSV-Beispiel fuer Feldmapping, weiterhin als Fallback lesbar
## Exportierte Struktur
Beim Export entsteht unter `-OutputPath` folgende Struktur:
```text
OutputPath
|-- Files
| |-- <Bibliothek>
| | |-- Unterordner
| | | |-- Dokument.pdf
| | | |-- Dokument.pdf.properties.json
|-- Lists
| |-- ListeA.json
|-- MappingTable.json
|-- manifest.csv
```
### Dateien
- Die Originaldatei wird in `Files\<Bibliothek>\...` gespeichert.
- Die Metadaten liegen direkt daneben als Sidecar-Datei:
`Dateiname.ext.properties.json`
- `manifest.csv` enthaelt ausserdem Container-Eintraege fuer Listen und Dokumentbibliotheken
### Listen
- Pro Liste wird genau eine JSON-Datei unter `Lists\` erzeugt.
- Die Eintraege enthalten insbesondere:
- `ContentTypeId`
- `FieldValues`
- `FieldTextValues`
- `Fields`
## Wichtige Metadaten
Fuer den Import sind vor allem diese Informationen relevant:
- `FieldValues`
- `FieldTextValues`
- `ContentTypeId`
- interne Feldnamen (`InternalName`)
Der Name des Inhaltstyps wird bewusst nicht als fuehrende Importinformation verwendet, da er sich im Zielsystem unterscheiden kann.
## MappingTable.json
Beim Export wird automatisch eine `MappingTable.json` erzeugt. Diese Datei enthaelt:
- `LibraryMappings`: Mapping von Quellbibliothek auf Zielbibliothek
- `ListMappings`: Mapping von Quellliste auf Zielliste
- `MetadataColumnMappings.SystemColumns`: erkannte Systemspalten
- `MetadataColumnMappings.CustomColumns`: erkannte eigene Fachspalten
Beispiel:
```json
{
"SchemaVersion": 1,
"GeneratedAtUtc": "2026-04-15T08:00:00.0000000Z",
"SourceWebUrl": "http://sharepoint/sites/Quelle",
"LibraryMappings": [
{
"ObjectType": "DocumentLibrary",
"SourceTitle": "Documents",
"TargetTitle": "Dokumente",
"BaseType": "DocumentLibrary",
"BaseTemplate": 101,
"RootFolderUrl": "/Documents",
"Hidden": false
}
],
"ListMappings": [
{
"ObjectType": "List",
"SourceTitle": "TestListe",
"TargetTitle": "ZielTestListe",
"BaseType": "GenericList",
"BaseTemplate": 100,
"RootFolderUrl": "/Lists/TestListe",
"Hidden": false
}
],
"MetadataColumnMappings": {
"SystemColumns": [
{
"ObjectType": "List",
"ContainerSourceTitle": "Kalender",
"SourceInternalName": "EventDate",
"SourceCanonicalInternalName": "EventDate",
"SourceSupportingInternalNames": [],
"TargetInternalName": "EventDate",
"DisplayName": "Beginnt",
"TypeAsString": "DateTime",
"Hidden": false,
"ReadOnly": false,
"Sealed": true,
"IsSystemColumn": true,
"ImportSupported": true
}
],
"CustomColumns": [
{
"ObjectType": "DocumentLibrary",
"ContainerSourceTitle": "Documents",
"SourceInternalName": "SecurityClearance",
"SourceCanonicalInternalName": "SecurityClearance",
"SourceSupportingInternalNames": [
"SecurityClearance_0"
],
"TargetInternalName": "GMNSecurityClearance",
"DisplayName": "Security Clearance",
"TypeAsString": "TaxonomyFieldType",
"Hidden": false,
"ReadOnly": false,
"Sealed": false,
"IsSystemColumn": false,
"ImportSupported": true
}
]
}
}
```
Fuer das Mapping ist vor allem relevant:
- `TargetTitle`: Zielname von Liste oder Bibliothek
- `TargetInternalName`: Zielfeld fuer die exportierte Metadatenspalte
- `SystemColumns`: SharePoint-Standardfelder wie `EventDate`, `EndDate`, `Title` oder `Created`
- `CustomColumns`: eigene Fachspalten, die im Ziel oft umbenannt oder anders aufgebaut sind
- `SourceSupportingInternalNames`: technische Begleitspalten wie `_0` werden nur noch informativ aufgefuehrt und nicht separat gemappt
- `ImportSupported`: steuert, ob eine Spalte beim Import ueberhaupt beruecksichtigt wird
- Taxonomy-Felder werden beim Import ueber den exportierten `TermGuid` gesetzt; dabei wird angenommen, dass derselbe Term im Ziel bereits mit identischer GUID existiert
Wenn eine Ziel-Liste oder Ziel-Bibliothek nicht existiert, gibt das Skript eine Warnung aus, dass dieser Container manuell angelegt werden soll.
## Parameter
### Pflichtparameter
- `SourceUrl`: Quell-Web fuer den Export
- `TargetUrl`: Ziel-Web fuer den Import
`OutputPath` ist optional. Standard ist `.\SPMigrationOutput` im aktuellen Verzeichnis.
### Exportparameter
- `Export`: fuehrt den Export aus
- `IncludeHiddenLibraries`: exportiert auch versteckte Bibliotheken
- `IncludeHiddenLists`: exportiert auch versteckte Listen
### Importparameter
- `Import`: fuehrt den Import aus einem vorhandenen Exportordner aus
- `MappingTable`: JSON-Datei mit Listen-, Bibliotheks- und Spalten-Mappings
- `ImportFiles`: importiert nur Dateien/Bibliotheken
- `ImportLists`: importiert nur Listen
- `Overwrite`: ueberschreibt vorhandene Dateien beim Import
Hinweis:
- Wenn weder `ImportFiles` noch `ImportLists` gesetzt sind, werden beim Import beide Bereiche verarbeitet.
- Wird `MappingTable` nicht angegeben, verwendet das Skript standardmaessig `OutputPath\MappingTable.json`.
- Die alte CSV-Variante wird fuer reines Feldmapping weiterhin als Fallback gelesen.
- Werden keine Schalter gesetzt, leitet das Skript den Modus weiterhin aus `SourceUrl` und `TargetUrl` ab.
- Wenn `Overwrite` nicht gesetzt ist und eine Datei bereits existiert, wird bei aktiver Versionierung eine neue Version geschrieben; ohne Versionierung wird die Datei uebersprungen.
- Nicht importierbare Systemfelder wie `Attachments`, `Created`, `Modified`, `Author` oder `Editor` werden automatisch aus der MappingTable herausgehalten bzw. beim Import uebersprungen.
- Vor dem Speichern prueft das Skript fehlende Pflichtfelder. Wenn ein einzelnes Listen- oder Datei-Metadatenobjekt trotzdem nicht gespeichert werden kann, wird es mit Kontext-Warnung uebersprungen und der Import laeuft weiter.
## Beispiele
### Nur Export
```powershell
.\Start-SPMigration.ps1 `
-SourceUrl "http://sharepoint/sites/Quelle" `
-Export `
-IncludeHiddenLists `
-IncludeHiddenLibraries
```
### Nur Import
```powershell
.\Start-SPMigration.ps1 `
-TargetUrl "http://sharepoint/sites/Ziel" `
-Import `
-MappingTable "C:\Temp\SP-Export\MappingTable.json"
```
### Export, MappingTable anpassen, dann Import
```powershell
.\Start-SPMigration.ps1 `
-SourceUrl "http://sharepoint/sites/Quelle" `
-OutputPath "C:\Temp\SP-Export" `
-Export
```
Danach `MappingTable.json` bearbeiten und dort `TargetTitle` sowie `TargetInternalName` anpassen.
Anschliessend:
```powershell
.\Start-SPMigration.ps1 `
-OutputPath "C:\Temp\SP-Export" `
-TargetUrl "http://sharepoint/sites/Ziel" `
-Import `
-MappingTable "C:\Temp\SP-Export\MappingTable.json"
```
### Nur Dateien importrelevant ausfuehren
```powershell
.\Start-SPMigration.ps1 `
-TargetUrl "http://sharepoint/sites/Ziel" `
-Import `
-MappingTable "C:\Temp\SP-Export\MappingTable.json" `
-ImportFiles `
-Overwrite
```
### Nur Listen importrelevant ausfuehren
```powershell
.\Start-SPMigration.ps1 `
-TargetUrl "http://sharepoint/sites/Ziel" `
-Import `
-MappingTable "C:\Temp\SP-Export\MappingTable.json" `
-ImportLists
```
## Aktuelles Verhalten beim Import
### Dokumentbibliotheken
- Dateien werden in die per `MappingTable.json` aufgeloeste Zielbibliothek importiert.
- Unterordner werden bei Bedarf angelegt.
- Metadaten werden anschliessend ueber die `MetadataColumnMappings` gesetzt.
### Listen
- Listeneintraege werden neu angelegt.
- Feldwerte werden ueber `FieldValues`, `FieldTextValues` und `MetadataColumnMappings` gemappt.
## Bekannte Einschraenkungen
- Die Zielaufloesung kann ueber `MappingTable.json` mit `TargetTitle` ueberschrieben werden.
- Listenanhaenge werden derzeit noch nicht physisch mit importiert.
- Ordner in normalen Listen werden beim Import derzeit uebersprungen.
- Fehlende Ziellisten oder Zielbibliotheken werden derzeit nicht automatisch angelegt; das Skript gibt stattdessen eine Warnung zur manuellen Anlage aus.
- Sehr spezielle Feldtypen koennen je nach Farm-Konfiguration zusaetzliche Anpassungen benoetigen.
- Das Skript ist fuer SharePoint On-Premise mit serverseitigem Objektmodell gedacht, nicht fuer SharePoint Online.
## Empfehlung
Zuerst immer mit `-Export` testen und die exportierten `*.properties.json`, Listen-JSONs und die `MappingTable.json` pruefen. Danach die Zielnamen und Feldmappings vervollstaendigen und erst dann den Import gegen das Zielsystem laufen lassen.