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-
MappingTablefuer Feld-, Listen- und Bibliotheks-Mappings erzeugen - beim Import dieselbe
MappingTablefuer 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:
Import-Module SharePointServer
Dateien im Projekt
Start-SPMigration.ps1: Hauptskript fuer Export und optionalen ImportFieldMapping.sample.csv: altes CSV-Beispiel fuer Feldmapping, weiterhin als Fallback lesbarcolumn-mapping-defaults.sample.json: Beispiel fuer wiederverwendbare Column-Mapping-Defaults
Exportierte Struktur
Beim Export entsteht unter -OutputPath folgende Struktur:
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.csventhaelt ausserdem Container-Eintraege fuer Listen und Dokumentbibliotheken
Listen
- Pro Liste wird genau eine JSON-Datei unter
Lists\erzeugt. - Die Eintraege enthalten insbesondere:
ContentTypeIdFieldValuesFieldTextValuesFields
Wichtige Metadaten
Fuer den Import sind vor allem diese Informationen relevant:
FieldValuesFieldTextValuesContentTypeId- 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 ZielbibliothekListMappings: Mapping von Quellliste auf ZiellisteMetadataColumnMappings.SystemColumns: erkannte SystemspaltenMetadataColumnMappings.CustomColumns: erkannte eigene Fachspalten
Beispiel:
{
"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 BibliothekTargetInternalName: Zielfeld fuer die exportierte MetadatenspalteSystemColumns: SharePoint-Standardfelder wieEventDate,EndDate,TitleoderCreatedCustomColumns: eigene Fachspalten, die im Ziel oft umbenannt oder anders aufgebaut sindSourceSupportingInternalNames: technische Begleitspalten wie_0werden nur noch informativ aufgefuehrt und nicht separat gemapptImportSupported: steuert, ob eine Spalte beim Import ueberhaupt beruecksichtigt wird- Taxonomy-Felder werden beim Import ueber den exportierten
TermGuidgesetzt; dabei wird angenommen, dass derselbe Term im Ziel bereits mit identischer GUID existiert - Die exportierte
WssIdwird bewusst nicht uebernommen: Sie ist nur innerhalb der Quell-SiteCollection gueltig. SharePoint loest beim Setzen des Feldwerts die zielseitigeWssIdauf und legt den Eintrag in derTaxonomyHiddenListbei Bedarf selbst an. Die Hidden List soll deshalb nicht separat migriert oder vorab befuellt werden.
Wenn eine Ziel-Liste oder Ziel-Bibliothek nicht existiert, gibt das Skript eine Warnung aus, dass dieser Container manuell angelegt werden soll.
Column Mapping Defaults
Wenn Bibliotheks- und Listen-Mappings je Migration unterschiedlich sind, die Spalten-Mappings aber gleich bleiben, kann die GUI eine separate Column-Defaults-Datei verwenden.
- Die
MappingTable.jsonbleibt migrationsspezifisch und enthaelt weiterhinLibraryMappings,ListMappingsund die konkret angewendetenMetadataColumnMappings. - Die Defaults-Datei enthaelt nur wiederverwendbare Spaltenregeln unter
Rules. - In der GUI kann ein Defaults-Pfad im Feld
ColumnDefaultsgepflegt werden. Nach einem Export werden vorhandene Defaults automatisch auf die frisch geladeneMappingTable.jsonangewendet und gespeichert. - Mit
Anwendenkoennen Defaults erneut auf die aktuelle MappingTable gelegt werden. Danach bleiben manuelle Anpassungen pro Migration weiterhin moeglich. - Mit
Speichernerzeugt die GUI aus den aktuellen Column-Mappings ein Defaults-Template. Gleichartige Spalten werden dabei aufContainerSourceTitle = "*"generalisiert; widerspruechliche Regeln bleiben container-spezifisch.
Regeln werden von spezifisch nach allgemein angewendet:
ObjectType + ContainerSourceTitle + SourceInternalNameObjectType + * + SourceInternalName* + ContainerSourceTitle + SourceInternalName* + * + SourceInternalName
Beispiel:
{
"SchemaVersion": 1,
"TemplateType": "ColumnMappings",
"Rules": [
{
"ObjectType": "*",
"ContainerSourceTitle": "*",
"SourceInternalName": "SecurityClearance",
"TargetInternalName": "GMNSecurityClearance",
"ImportSupported": true
}
]
}
Parameter
Pflichtparameter
SourceUrl: Quell-Web fuer den ExportTargetUrl: Ziel-Web fuer den Import
OutputPath ist optional. Standard ist .\SPMigrationOutput im aktuellen Verzeichnis.
Exportparameter
Export: fuehrt den Export ausIncludeHiddenLibraries: exportiert auch versteckte BibliothekenIncludeHiddenLists: exportiert auch versteckte Listen
Importparameter
Import: fuehrt den Import aus einem vorhandenen Exportordner ausMappingTable: JSON-Datei mit Listen-, Bibliotheks- und Spalten-MappingsImportFiles: importiert nur Dateien/BibliothekenImportLists: importiert nur ListenOverwrite: ueberschreibt vorhandene Dateien beim Import
Hinweis:
- Wenn weder
ImportFilesnochImportListsgesetzt sind, werden beim Import beide Bereiche verarbeitet. - Wird
MappingTablenicht angegeben, verwendet das Skript standardmaessigOutputPath\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
SourceUrlundTargetUrlab. - Wenn
Overwritenicht 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,AuthoroderEditorwerden 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.
- Beim Listenimport legt das Skript bei Bedarf ein verstecktes Textfeld
StartSPMigrationSourceUniqueIdin der Zielliste an. Wiederholte Imports aktualisieren damit vorhandene Elemente anhand der exportierten Source-UniqueIdstatt sie erneut anzulegen.
Beispiele
Nur Export
.\Start-SPMigration.ps1 `
-SourceUrl "http://sharepoint/sites/Quelle" `
-Export `
-IncludeHiddenLists `
-IncludeHiddenLibraries
Nur Import
.\Start-SPMigration.ps1 `
-TargetUrl "http://sharepoint/sites/Ziel" `
-Import `
-MappingTable "C:\Temp\SP-Export\MappingTable.json"
Export, MappingTable anpassen, dann Import
.\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:
.\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
.\Start-SPMigration.ps1 `
-TargetUrl "http://sharepoint/sites/Ziel" `
-Import `
-MappingTable "C:\Temp\SP-Export\MappingTable.json" `
-ImportFiles `
-Overwrite
Nur Listen importrelevant ausfuehren
.\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.jsonaufgeloeste Zielbibliothek importiert. - Unterordner werden bei Bedarf angelegt.
- Metadaten werden anschliessend ueber die
MetadataColumnMappingsgesetzt.
Listen
- Listeneintraege werden neu angelegt oder bei erneutem Import ueber
StartSPMigrationSourceUniqueIdwiedergefunden und aktualisiert. - Feldwerte werden ueber
FieldValues,FieldTextValuesundMetadataColumnMappingsgemappt.
GUI-Logging und Mapping-Bearbeitung
- Beim Import protokolliert die GUI fuer jeden verarbeiteten Columnwert, ob die Zuweisung am Item erfolgreich war oder mit welchem Fehler sie uebersprungen wurde. Das Log nennt Container bzw. Item sowie Quell- und Zielspalte, schreibt aber nicht den eigentlichen Feldinhalt mit.
- In den Mapping-Tabs
Bibliotheken,Listen,System ColumnsundCustom Columnskann eine Zeile per Rechtsklick undZeile loeschenvollstaendig entfernt werden. Beim Speichern wird sie entsprechend nicht mehr in dieMappingTable.jsongeschrieben.
Bekannte Einschraenkungen
- Die Zielaufloesung kann ueber
MappingTable.jsonmitTargetTitleueberschrieben 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.