adding List / Library Mapping via Manifest File
This commit is contained in:
57
README.md
57
README.md
@@ -9,6 +9,7 @@ Das Skript kann:
|
|||||||
- normale SharePoint-Listen und deren Eintraege exportieren
|
- normale SharePoint-Listen und deren Eintraege exportieren
|
||||||
- exportierte Inhalte wieder in ein Ziel-Web importieren
|
- exportierte Inhalte wieder in ein Ziel-Web importieren
|
||||||
- Feldwerte ueber eine Mapping-CSV von Quell- auf Ziel-InternalNames abbilden
|
- Feldwerte ueber eine Mapping-CSV von Quell- auf Ziel-InternalNames abbilden
|
||||||
|
- Listen- und Bibliotheksnamen ueber `manifest.csv` auf Zielnamen abbilden
|
||||||
|
|
||||||
## Voraussetzungen
|
## Voraussetzungen
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ OutputPath
|
|||||||
- Die Originaldatei wird in `Files\<Bibliothek>\...` gespeichert.
|
- Die Originaldatei wird in `Files\<Bibliothek>\...` gespeichert.
|
||||||
- Die Metadaten liegen direkt daneben als Sidecar-Datei:
|
- Die Metadaten liegen direkt daneben als Sidecar-Datei:
|
||||||
`Dateiname.ext.properties.json`
|
`Dateiname.ext.properties.json`
|
||||||
|
- `manifest.csv` enthaelt ausserdem Container-Eintraege fuer Listen und Dokumentbibliotheken
|
||||||
|
|
||||||
### Listen
|
### Listen
|
||||||
|
|
||||||
@@ -86,6 +88,33 @@ Bedeutung:
|
|||||||
- `SourceInternalName`: interner Feldname aus dem Export
|
- `SourceInternalName`: interner Feldname aus dem Export
|
||||||
- `TargetInternalName`: interner Feldname im Zielsystem
|
- `TargetInternalName`: interner Feldname im Zielsystem
|
||||||
|
|
||||||
|
## manifest.csv fuer Listen- und Bibliotheksmapping
|
||||||
|
|
||||||
|
Beim Export wird fuer jede Liste und jede Dokumentbibliothek eine Container-Zeile in `manifest.csv` geschrieben.
|
||||||
|
|
||||||
|
Wichtige Spalten:
|
||||||
|
|
||||||
|
- `RecordType`
|
||||||
|
- `ObjectType`
|
||||||
|
- `SourceTitle`
|
||||||
|
- `TargetTitle`
|
||||||
|
- `BaseTemplate`
|
||||||
|
|
||||||
|
Fuer das Mapping ist insbesondere `TargetTitle` gedacht:
|
||||||
|
|
||||||
|
- leer: das Skript sucht im Ziel mit dem Quellnamen
|
||||||
|
- gesetzt: das Skript sucht im Ziel mit dem Wert aus `TargetTitle`
|
||||||
|
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
```csv
|
||||||
|
RecordType;ObjectType;SourceWebUrl;SourceTitle;TargetTitle;BaseType;BaseTemplate;RootFolderUrl;SourceServerRelativeUrl;FileName;FileUniqueId;FileLength;LocalFilePath;LocalMetadataPath;ExportedAtUtc
|
||||||
|
Container;DocumentLibrary;http://clshp001/;Documents;Dokumente;DocumentLibrary;101;/Documents;/Documents;;;;;;
|
||||||
|
Container;List;http://clshp001/;TestListe;ZielTestListe;GenericList;100;/Lists/TestListe;/Lists/TestListe;;;;;;
|
||||||
|
```
|
||||||
|
|
||||||
|
Wenn eine Ziel-Liste oder Ziel-Bibliothek nicht existiert, gibt das Skript eine Warnung aus, dass dieser Container manuell angelegt werden soll.
|
||||||
|
|
||||||
## Parameter
|
## Parameter
|
||||||
|
|
||||||
### Pflichtparameter
|
### Pflichtparameter
|
||||||
@@ -98,6 +127,7 @@ Bedeutung:
|
|||||||
- `IncludeHiddenLibraries`: exportiert auch versteckte Bibliotheken
|
- `IncludeHiddenLibraries`: exportiert auch versteckte Bibliotheken
|
||||||
- `IncludeHiddenLists`: exportiert auch versteckte Listen
|
- `IncludeHiddenLists`: exportiert auch versteckte Listen
|
||||||
- `ExportOnly`: fuehrt nur den Export aus
|
- `ExportOnly`: fuehrt nur den Export aus
|
||||||
|
- `ImportOnly`: fuehrt nur den Import aus einem vorhandenen Exportordner aus
|
||||||
|
|
||||||
### Importparameter
|
### Importparameter
|
||||||
|
|
||||||
@@ -111,6 +141,7 @@ Hinweis:
|
|||||||
|
|
||||||
- Wenn weder `ImportFiles` noch `ImportLists` gesetzt sind, werden beim Import beide Bereiche verarbeitet.
|
- Wenn weder `ImportFiles` noch `ImportLists` gesetzt sind, werden beim Import beide Bereiche verarbeitet.
|
||||||
- Wenn `ExportOnly` gesetzt ist, wird kein Import gestartet.
|
- Wenn `ExportOnly` gesetzt ist, wird kein Import gestartet.
|
||||||
|
- Wenn `ImportOnly` gesetzt ist, wird kein neuer Export gestartet.
|
||||||
|
|
||||||
## Beispiele
|
## Beispiele
|
||||||
|
|
||||||
@@ -133,6 +164,27 @@ Hinweis:
|
|||||||
-MappingCsvPath ".\FieldMapping.sample.csv"
|
-MappingCsvPath ".\FieldMapping.sample.csv"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Export, manifest.csv anpassen, dann nur Import
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Start-SPMigration.ps1 `
|
||||||
|
-WebUrl "http://sharepoint/sites/Quelle" `
|
||||||
|
-OutputPath "C:\Temp\SP-Export" `
|
||||||
|
-ExportOnly
|
||||||
|
```
|
||||||
|
|
||||||
|
Danach `manifest.csv` bearbeiten und `TargetTitle` fuer Listen oder Bibliotheken setzen.
|
||||||
|
|
||||||
|
Anschliessend:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Start-SPMigration.ps1 `
|
||||||
|
-OutputPath "C:\Temp\SP-Export" `
|
||||||
|
-TargetWebUrl "http://sharepoint/sites/Ziel" `
|
||||||
|
-MappingCsvPath ".\FieldMapping.sample.csv" `
|
||||||
|
-ImportOnly
|
||||||
|
```
|
||||||
|
|
||||||
### Nur Dateien importrelevant ausfuehren
|
### Nur Dateien importrelevant ausfuehren
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -160,7 +212,7 @@ Hinweis:
|
|||||||
|
|
||||||
### Dokumentbibliotheken
|
### Dokumentbibliotheken
|
||||||
|
|
||||||
- Dateien werden in die gleichnamige Zielbibliothek importiert.
|
- Dateien werden in die per `manifest.csv` aufgeloeste Zielbibliothek importiert.
|
||||||
- Unterordner werden bei Bedarf angelegt.
|
- Unterordner werden bei Bedarf angelegt.
|
||||||
- Metadaten werden anschliessend ueber das CSV-Mapping gesetzt.
|
- Metadaten werden anschliessend ueber das CSV-Mapping gesetzt.
|
||||||
|
|
||||||
@@ -171,9 +223,10 @@ Hinweis:
|
|||||||
|
|
||||||
## Bekannte Einschraenkungen
|
## Bekannte Einschraenkungen
|
||||||
|
|
||||||
- Zielbibliotheken und Ziellisten werden aktuell ueber den Titel aufgeloest.
|
- Die Zielaufloesung kann ueber `manifest.csv` mit `TargetTitle` ueberschrieben werden.
|
||||||
- Listenanhaenge werden derzeit noch nicht physisch mit importiert.
|
- Listenanhaenge werden derzeit noch nicht physisch mit importiert.
|
||||||
- Ordner in normalen Listen werden beim Import derzeit uebersprungen.
|
- 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.
|
- 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.
|
- Das Skript ist fuer SharePoint On-Premise mit serverseitigem Objektmodell gedacht, nicht fuer SharePoint Online.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory = $true)]
|
|
||||||
[string]$WebUrl,
|
[string]$WebUrl,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
@@ -20,7 +19,9 @@ param(
|
|||||||
|
|
||||||
[switch]$OverwriteFiles,
|
[switch]$OverwriteFiles,
|
||||||
|
|
||||||
[switch]$ExportOnly
|
[switch]$ExportOnly,
|
||||||
|
|
||||||
|
[switch]$ImportOnly
|
||||||
)
|
)
|
||||||
|
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
@@ -62,7 +63,9 @@ function Invoke-MigrationImport {
|
|||||||
$resolvedInputPath = [System.IO.Path]::GetFullPath($InputPath)
|
$resolvedInputPath = [System.IO.Path]::GetFullPath($InputPath)
|
||||||
$filesRootPath = [System.IO.Path]::Combine($resolvedInputPath, "Files")
|
$filesRootPath = [System.IO.Path]::Combine($resolvedInputPath, "Files")
|
||||||
$listsRootPath = [System.IO.Path]::Combine($resolvedInputPath, "Lists")
|
$listsRootPath = [System.IO.Path]::Combine($resolvedInputPath, "Lists")
|
||||||
|
$manifestPath = [System.IO.Path]::Combine($resolvedInputPath, "manifest.csv")
|
||||||
$fieldMapping = Get-FieldMapping -Path $MappingCsvPath
|
$fieldMapping = Get-FieldMapping -Path $MappingCsvPath
|
||||||
|
$containerManifestMap = Get-ContainerManifestMap -ManifestRows (Read-ManifestRows -ManifestPath $manifestPath)
|
||||||
|
|
||||||
if ($fieldMapping.Count -eq 0) {
|
if ($fieldMapping.Count -eq 0) {
|
||||||
throw "Die Mapping-CSV enthaelt keine gueltigen Zuordnungen."
|
throw "Die Mapping-CSV enthaelt keine gueltigen Zuordnungen."
|
||||||
@@ -82,11 +85,11 @@ function Invoke-MigrationImport {
|
|||||||
$targetWeb = Get-SPWeb -Identity $TargetWebUrl -ErrorAction Stop
|
$targetWeb = Get-SPWeb -Identity $TargetWebUrl -ErrorAction Stop
|
||||||
|
|
||||||
if ($shouldImportFiles) {
|
if ($shouldImportFiles) {
|
||||||
Import-SPDocumentLibraries -Web $targetWeb -FilesRootPath $filesRootPath -FieldMapping $fieldMapping -OverwriteFiles:$OverwriteFiles
|
Import-SPDocumentLibraries -Web $targetWeb -FilesRootPath $filesRootPath -FieldMapping $fieldMapping -ContainerManifestMap $containerManifestMap -OverwriteFiles:$OverwriteFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($shouldImportLists) {
|
if ($shouldImportLists) {
|
||||||
Import-SPLists -Web $targetWeb -ListsRootPath $listsRootPath -FieldMapping $fieldMapping
|
Import-SPLists -Web $targetWeb -ListsRootPath $listsRootPath -FieldMapping $fieldMapping -ContainerManifestMap $containerManifestMap
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host ("Import abgeschlossen. Quelle: {0}" -f $resolvedInputPath)
|
Write-Host ("Import abgeschlossen. Quelle: {0}" -f $resolvedInputPath)
|
||||||
@@ -515,6 +518,73 @@ function Write-ManifestRow {
|
|||||||
$Row | Export-Csv -Path $ManifestPath -NoTypeInformation -Delimiter ";" -Encoding UTF8 -Append:$append
|
$Row | Export-Csv -Path $ManifestPath -NoTypeInformation -Delimiter ";" -Encoding UTF8 -Append:$append
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function New-ManifestRow {
|
||||||
|
param(
|
||||||
|
[string]$RecordType = "",
|
||||||
|
[string]$ObjectType = "",
|
||||||
|
[string]$SourceWebUrl = "",
|
||||||
|
[string]$SourceTitle = "",
|
||||||
|
[string]$TargetTitle = "",
|
||||||
|
[string]$BaseType = "",
|
||||||
|
[string]$BaseTemplate = "",
|
||||||
|
[string]$RootFolderUrl = "",
|
||||||
|
[string]$SourceServerRelativeUrl = "",
|
||||||
|
[string]$FileName = "",
|
||||||
|
[string]$FileUniqueId = "",
|
||||||
|
[string]$FileLength = "",
|
||||||
|
[string]$LocalFilePath = "",
|
||||||
|
[string]$LocalMetadataPath = "",
|
||||||
|
[string]$ExportedAtUtc = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
return [PSCustomObject]@{
|
||||||
|
RecordType = $RecordType
|
||||||
|
ObjectType = $ObjectType
|
||||||
|
SourceWebUrl = $SourceWebUrl
|
||||||
|
SourceTitle = $SourceTitle
|
||||||
|
TargetTitle = $TargetTitle
|
||||||
|
BaseType = $BaseType
|
||||||
|
BaseTemplate = $BaseTemplate
|
||||||
|
RootFolderUrl = $RootFolderUrl
|
||||||
|
SourceServerRelativeUrl = $SourceServerRelativeUrl
|
||||||
|
FileName = $FileName
|
||||||
|
FileUniqueId = $FileUniqueId
|
||||||
|
FileLength = $FileLength
|
||||||
|
LocalFilePath = $LocalFilePath
|
||||||
|
LocalMetadataPath = $LocalMetadataPath
|
||||||
|
ExportedAtUtc = $ExportedAtUtc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-ContainerManifestRow {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[Microsoft.SharePoint.SPWeb]$Web,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[Microsoft.SharePoint.SPList]$List,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$ManifestPath
|
||||||
|
)
|
||||||
|
|
||||||
|
$objectType = if ($List.BaseType -eq [Microsoft.SharePoint.SPBaseType]::DocumentLibrary) { "DocumentLibrary" } else { "List" }
|
||||||
|
|
||||||
|
$manifestRow = New-ManifestRow `
|
||||||
|
-RecordType "Container" `
|
||||||
|
-ObjectType $objectType `
|
||||||
|
-SourceWebUrl $Web.Url `
|
||||||
|
-SourceTitle $List.Title `
|
||||||
|
-TargetTitle "" `
|
||||||
|
-BaseType $List.BaseType.ToString() `
|
||||||
|
-BaseTemplate ([string][int]$List.BaseTemplate) `
|
||||||
|
-RootFolderUrl $List.RootFolder.ServerRelativeUrl `
|
||||||
|
-SourceServerRelativeUrl $List.RootFolder.ServerRelativeUrl `
|
||||||
|
-ExportedAtUtc ([System.DateTime]::UtcNow.ToString("o"))
|
||||||
|
|
||||||
|
Write-ManifestRow -Row $manifestRow -ManifestPath $ManifestPath
|
||||||
|
}
|
||||||
|
|
||||||
function Get-RelativeFilePathSegments {
|
function Get-RelativeFilePathSegments {
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
@@ -590,17 +660,22 @@ function Export-SPFile {
|
|||||||
$metadata = Get-FileMetadataObject -Web $Web -List $List -File $File
|
$metadata = Get-FileMetadataObject -Web $Web -List $List -File $File
|
||||||
Write-MetadataJson -MetadataObject $metadata -Path $metadataPath
|
Write-MetadataJson -MetadataObject $metadata -Path $metadataPath
|
||||||
|
|
||||||
$manifestRow = [PSCustomObject]@{
|
$manifestRow = New-ManifestRow `
|
||||||
WebUrl = $Web.Url
|
-RecordType "File" `
|
||||||
LibraryTitle = $List.Title
|
-ObjectType "DocumentLibrary" `
|
||||||
FileName = $File.Name
|
-SourceWebUrl $Web.Url `
|
||||||
FileServerRelativeUrl = $File.ServerRelativeUrl
|
-SourceTitle $List.Title `
|
||||||
FileUniqueId = $File.UniqueId.ToString()
|
-TargetTitle "" `
|
||||||
FileLength = $File.Length
|
-BaseType $List.BaseType.ToString() `
|
||||||
LocalFilePath = $localFilePath
|
-BaseTemplate ([string][int]$List.BaseTemplate) `
|
||||||
LocalMetadataPath = $metadataPath
|
-RootFolderUrl $List.RootFolder.ServerRelativeUrl `
|
||||||
ExportedAtUtc = [System.DateTime]::UtcNow.ToString("o")
|
-SourceServerRelativeUrl $File.ServerRelativeUrl `
|
||||||
}
|
-FileName $File.Name `
|
||||||
|
-FileUniqueId $File.UniqueId.ToString() `
|
||||||
|
-FileLength ([string]$File.Length) `
|
||||||
|
-LocalFilePath $localFilePath `
|
||||||
|
-LocalMetadataPath $metadataPath `
|
||||||
|
-ExportedAtUtc ([System.DateTime]::UtcNow.ToString("o"))
|
||||||
|
|
||||||
Write-ManifestRow -Row $manifestRow -ManifestPath $ManifestPath
|
Write-ManifestRow -Row $manifestRow -ManifestPath $ManifestPath
|
||||||
}
|
}
|
||||||
@@ -655,6 +730,7 @@ function Export-SPDocumentLibrary {
|
|||||||
)
|
)
|
||||||
|
|
||||||
Write-Host ("Exportiere Bibliothek: {0}" -f $List.Title)
|
Write-Host ("Exportiere Bibliothek: {0}" -f $List.Title)
|
||||||
|
Write-ContainerManifestRow -Web $Web -List $List -ManifestPath $ManifestPath
|
||||||
$fileCount = 0
|
$fileCount = 0
|
||||||
|
|
||||||
Export-SPFolder -Web $Web -List $List -Folder $List.RootFolder -FilesRootPath $FilesRootPath -ManifestPath $ManifestPath -FileCount ([ref]$fileCount)
|
Export-SPFolder -Web $Web -List $List -Folder $List.RootFolder -FilesRootPath $FilesRootPath -ManifestPath $ManifestPath -FileCount ([ref]$fileCount)
|
||||||
@@ -671,10 +747,14 @@ function Export-SPList {
|
|||||||
[Microsoft.SharePoint.SPList]$List,
|
[Microsoft.SharePoint.SPList]$List,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[string]$ListsRootPath
|
[string]$ListsRootPath,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$ManifestPath
|
||||||
)
|
)
|
||||||
|
|
||||||
Write-Host ("Exportiere Liste: {0}" -f $List.Title)
|
Write-Host ("Exportiere Liste: {0}" -f $List.Title)
|
||||||
|
Write-ContainerManifestRow -Web $Web -List $List -ManifestPath $ManifestPath
|
||||||
|
|
||||||
$safeListName = Get-SafePathSegment $List.Title
|
$safeListName = Get-SafePathSegment $List.Title
|
||||||
$listPath = [System.IO.Path]::Combine($ListsRootPath, "$safeListName.json")
|
$listPath = [System.IO.Path]::Combine($ListsRootPath, "$safeListName.json")
|
||||||
@@ -732,6 +812,105 @@ function Get-ObjectPropertyValue {
|
|||||||
return $property.Value
|
return $property.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Read-ManifestRows {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$ManifestPath
|
||||||
|
)
|
||||||
|
|
||||||
|
if (-not [System.IO.File]::Exists($ManifestPath)) {
|
||||||
|
return @()
|
||||||
|
}
|
||||||
|
|
||||||
|
return @(Import-Csv -Path $ManifestPath -Delimiter ";")
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-ContainerManifestEntryKey {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$ObjectType,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$SourceTitle
|
||||||
|
)
|
||||||
|
|
||||||
|
return ("{0}|{1}" -f $ObjectType.Trim(), $SourceTitle.Trim()).ToLowerInvariant()
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-ContainerManifestMap {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[object[]]$ManifestRows
|
||||||
|
)
|
||||||
|
|
||||||
|
$containerMap = @{}
|
||||||
|
|
||||||
|
foreach ($row in $ManifestRows) {
|
||||||
|
$recordType = [string](Get-ObjectPropertyValue -Object $row -PropertyName "RecordType")
|
||||||
|
$sourceTitle = [string](Get-ObjectPropertyValue -Object $row -PropertyName "SourceTitle")
|
||||||
|
$objectType = [string](Get-ObjectPropertyValue -Object $row -PropertyName "ObjectType")
|
||||||
|
|
||||||
|
if ($recordType -ne "Container" -or [string]::IsNullOrWhiteSpace($sourceTitle) -or [string]::IsNullOrWhiteSpace($objectType)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = Get-ContainerManifestEntryKey -ObjectType $objectType -SourceTitle $sourceTitle
|
||||||
|
$containerMap[$key] = $row
|
||||||
|
}
|
||||||
|
|
||||||
|
return $containerMap
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-TargetContainerTitle {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[hashtable]$ContainerManifestMap,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$ObjectType,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$SourceTitle
|
||||||
|
)
|
||||||
|
|
||||||
|
$key = Get-ContainerManifestEntryKey -ObjectType $ObjectType -SourceTitle $SourceTitle
|
||||||
|
$manifestEntry = $ContainerManifestMap[$key]
|
||||||
|
|
||||||
|
if ($null -eq $manifestEntry) {
|
||||||
|
return $SourceTitle
|
||||||
|
}
|
||||||
|
|
||||||
|
$targetTitle = [string](Get-ObjectPropertyValue -Object $manifestEntry -PropertyName "TargetTitle")
|
||||||
|
if ([string]::IsNullOrWhiteSpace($targetTitle)) {
|
||||||
|
return $SourceTitle
|
||||||
|
}
|
||||||
|
|
||||||
|
return $targetTitle.Trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-ContainerHasExplicitTargetMapping {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[hashtable]$ContainerManifestMap,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$ObjectType,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$SourceTitle
|
||||||
|
)
|
||||||
|
|
||||||
|
$key = Get-ContainerManifestEntryKey -ObjectType $ObjectType -SourceTitle $SourceTitle
|
||||||
|
$manifestEntry = $ContainerManifestMap[$key]
|
||||||
|
|
||||||
|
if ($null -eq $manifestEntry) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
$targetTitle = [string](Get-ObjectPropertyValue -Object $manifestEntry -PropertyName "TargetTitle")
|
||||||
|
return -not [string]::IsNullOrWhiteSpace($targetTitle)
|
||||||
|
}
|
||||||
|
|
||||||
function Test-ObjectHasProperty {
|
function Test-ObjectHasProperty {
|
||||||
param(
|
param(
|
||||||
$Object,
|
$Object,
|
||||||
@@ -1211,6 +1390,9 @@ function Import-SPDocumentLibraries {
|
|||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[System.Collections.IDictionary]$FieldMapping,
|
[System.Collections.IDictionary]$FieldMapping,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[hashtable]$ContainerManifestMap,
|
||||||
|
|
||||||
[switch]$OverwriteFiles
|
[switch]$OverwriteFiles
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1232,21 +1414,27 @@ function Import-SPDocumentLibraries {
|
|||||||
$metadata = Read-JsonFile -Path $metadataFile.FullName
|
$metadata = Read-JsonFile -Path $metadataFile.FullName
|
||||||
$libraryMetadata = Get-ObjectPropertyValue -Object $metadata -PropertyName "Library"
|
$libraryMetadata = Get-ObjectPropertyValue -Object $metadata -PropertyName "Library"
|
||||||
$itemMetadata = Get-ObjectPropertyValue -Object $metadata -PropertyName "Item"
|
$itemMetadata = Get-ObjectPropertyValue -Object $metadata -PropertyName "Item"
|
||||||
$libraryTitle = [string](Get-ObjectPropertyValue -Object $libraryMetadata -PropertyName "Title")
|
$sourceLibraryTitle = [string](Get-ObjectPropertyValue -Object $libraryMetadata -PropertyName "Title")
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($libraryTitle)) {
|
if ([string]::IsNullOrWhiteSpace($sourceLibraryTitle)) {
|
||||||
Write-Warning ("Bibliothekstitel fehlt in: {0}" -f $metadataFile.FullName)
|
Write-Warning ("Bibliothekstitel fehlt in: {0}" -f $metadataFile.FullName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
$targetLibrary = $Web.Lists.TryGetList($libraryTitle)
|
$targetLibraryTitle = Get-TargetContainerTitle -ContainerManifestMap $ContainerManifestMap -ObjectType "DocumentLibrary" -SourceTitle $sourceLibraryTitle
|
||||||
|
$targetLibrary = $Web.Lists.TryGetList($targetLibraryTitle)
|
||||||
if ($null -eq $targetLibrary) {
|
if ($null -eq $targetLibrary) {
|
||||||
Write-Warning ("Zielbibliothek nicht gefunden: {0}" -f $libraryTitle)
|
if (Test-ContainerHasExplicitTargetMapping -ContainerManifestMap $ContainerManifestMap -ObjectType "DocumentLibrary" -SourceTitle $sourceLibraryTitle) {
|
||||||
|
Write-Warning ("Zielbibliothek '{0}' fuer Quellbibliothek '{1}' nicht gefunden. Bitte diese Bibliothek im Ziel manuell anlegen." -f $targetLibraryTitle, $sourceLibraryTitle)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ("Zielbibliothek '{0}' nicht gefunden und kein TargetTitle im manifest.csv gepflegt. Bitte Bibliothek manuell anlegen oder TargetTitle im Manifest setzen." -f $sourceLibraryTitle)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($targetLibrary.BaseType -ne [Microsoft.SharePoint.SPBaseType]::DocumentLibrary) {
|
if ($targetLibrary.BaseType -ne [Microsoft.SharePoint.SPBaseType]::DocumentLibrary) {
|
||||||
Write-Warning ("Zielliste ist keine Dokumentbibliothek: {0}" -f $libraryTitle)
|
Write-Warning ("Zielliste ist keine Dokumentbibliothek: {0}" -f $targetLibraryTitle)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1286,7 +1474,10 @@ function Import-SPLists {
|
|||||||
[string]$ListsRootPath,
|
[string]$ListsRootPath,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[System.Collections.IDictionary]$FieldMapping
|
[System.Collections.IDictionary]$FieldMapping,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[hashtable]$ContainerManifestMap
|
||||||
)
|
)
|
||||||
|
|
||||||
if (-not [System.IO.Directory]::Exists($ListsRootPath)) {
|
if (-not [System.IO.Directory]::Exists($ListsRootPath)) {
|
||||||
@@ -1301,35 +1492,41 @@ function Import-SPLists {
|
|||||||
$listExport = Read-JsonFile -Path $listFile.FullName
|
$listExport = Read-JsonFile -Path $listFile.FullName
|
||||||
$listMetadata = Get-ObjectPropertyValue -Object $listExport -PropertyName "List"
|
$listMetadata = Get-ObjectPropertyValue -Object $listExport -PropertyName "List"
|
||||||
$items = @(Get-ObjectPropertyValue -Object $listExport -PropertyName "Items" -DefaultValue @())
|
$items = @(Get-ObjectPropertyValue -Object $listExport -PropertyName "Items" -DefaultValue @())
|
||||||
$listTitle = [string](Get-ObjectPropertyValue -Object $listMetadata -PropertyName "Title")
|
$sourceListTitle = [string](Get-ObjectPropertyValue -Object $listMetadata -PropertyName "Title")
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($listTitle)) {
|
if ([string]::IsNullOrWhiteSpace($sourceListTitle)) {
|
||||||
Write-Warning ("Listentitel fehlt in: {0}" -f $listFile.FullName)
|
Write-Warning ("Listentitel fehlt in: {0}" -f $listFile.FullName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
$targetList = $Web.Lists.TryGetList($listTitle)
|
$targetListTitle = Get-TargetContainerTitle -ContainerManifestMap $ContainerManifestMap -ObjectType "List" -SourceTitle $sourceListTitle
|
||||||
|
$targetList = $Web.Lists.TryGetList($targetListTitle)
|
||||||
if ($null -eq $targetList) {
|
if ($null -eq $targetList) {
|
||||||
Write-Warning ("Zielliste nicht gefunden: {0}" -f $listTitle)
|
if (Test-ContainerHasExplicitTargetMapping -ContainerManifestMap $ContainerManifestMap -ObjectType "List" -SourceTitle $sourceListTitle) {
|
||||||
|
Write-Warning ("Zielliste '{0}' fuer Quellliste '{1}' nicht gefunden. Bitte diese Liste im Ziel manuell anlegen." -f $targetListTitle, $sourceListTitle)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning ("Zielliste '{0}' nicht gefunden und kein TargetTitle im manifest.csv gepflegt. Bitte Liste manuell anlegen oder TargetTitle im Manifest setzen." -f $sourceListTitle)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($targetList.BaseType -eq [Microsoft.SharePoint.SPBaseType]::DocumentLibrary) {
|
if ($targetList.BaseType -eq [Microsoft.SharePoint.SPBaseType]::DocumentLibrary) {
|
||||||
Write-Warning ("Liste ist eine Dokumentbibliothek und wird im Listenimport uebersprungen: {0}" -f $listTitle)
|
Write-Warning ("Liste ist eine Dokumentbibliothek und wird im Listenimport uebersprungen: {0}" -f $targetListTitle)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host ("Importiere Liste: {0}" -f $listTitle)
|
Write-Host ("Importiere Liste: {0}" -f $targetListTitle)
|
||||||
|
|
||||||
foreach ($sourceItem in $items) {
|
foreach ($sourceItem in $items) {
|
||||||
$fileSystemObjectType = [string](Get-ObjectPropertyValue -Object $sourceItem -PropertyName "FileSystemObjectType")
|
$fileSystemObjectType = [string](Get-ObjectPropertyValue -Object $sourceItem -PropertyName "FileSystemObjectType")
|
||||||
if ($fileSystemObjectType -eq "Folder") {
|
if ($fileSystemObjectType -eq "Folder") {
|
||||||
Write-Warning ("Ordner in normalen Listen werden in dieser Version uebersprungen: {0}" -f $listTitle)
|
Write-Warning ("Ordner in normalen Listen werden in dieser Version uebersprungen: {0}" -f $targetListTitle)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Get-ObjectPropertyValue -Object $sourceItem -PropertyName "HasAttachments" -DefaultValue $false)) {
|
if ((Get-ObjectPropertyValue -Object $sourceItem -PropertyName "HasAttachments" -DefaultValue $false)) {
|
||||||
Write-Warning ("Listenanlagen wurden im Export nicht physisch gesichert und werden uebersprungen. Liste: {0}, ItemId: {1}" -f $listTitle, (Get-ObjectPropertyValue -Object $sourceItem -PropertyName "Id"))
|
Write-Warning ("Listenanlagen wurden im Export nicht physisch gesichert und werden uebersprungen. Liste: {0}, ItemId: {1}" -f $targetListTitle, (Get-ObjectPropertyValue -Object $sourceItem -PropertyName "Id"))
|
||||||
}
|
}
|
||||||
|
|
||||||
$targetItem = $targetList.Items.Add()
|
$targetItem = $targetList.Items.Add()
|
||||||
@@ -1346,6 +1543,30 @@ $filesRootPath = [System.IO.Path]::Combine($resolvedOutputPath, "Files")
|
|||||||
$listsRootPath = [System.IO.Path]::Combine($resolvedOutputPath, "Lists")
|
$listsRootPath = [System.IO.Path]::Combine($resolvedOutputPath, "Lists")
|
||||||
$manifestPath = [System.IO.Path]::Combine($resolvedOutputPath, "manifest.csv")
|
$manifestPath = [System.IO.Path]::Combine($resolvedOutputPath, "manifest.csv")
|
||||||
|
|
||||||
|
$importConfigurationProvided =
|
||||||
|
(-not [string]::IsNullOrWhiteSpace($TargetWebUrl)) -or
|
||||||
|
(-not [string]::IsNullOrWhiteSpace($MappingCsvPath)) -or
|
||||||
|
$ImportFiles -or
|
||||||
|
$ImportLists -or
|
||||||
|
$OverwriteFiles
|
||||||
|
|
||||||
|
if ($ExportOnly -and $ImportOnly) {
|
||||||
|
throw "ExportOnly und ImportOnly koennen nicht gleichzeitig gesetzt werden."
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ImportOnly) {
|
||||||
|
if ([string]::IsNullOrWhiteSpace($TargetWebUrl) -or [string]::IsNullOrWhiteSpace($MappingCsvPath)) {
|
||||||
|
throw "Fuer ImportOnly muessen TargetWebUrl und MappingCsvPath angegeben werden."
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-MigrationImport -InputPath $resolvedOutputPath -TargetWebUrl $TargetWebUrl -MappingCsvPath $MappingCsvPath -ImportFiles:$ImportFiles -ImportLists:$ImportLists -OverwriteFiles:$OverwriteFiles
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($WebUrl)) {
|
||||||
|
throw "Fuer den Export muss WebUrl angegeben werden."
|
||||||
|
}
|
||||||
|
|
||||||
Ensure-Directory -Path $resolvedOutputPath
|
Ensure-Directory -Path $resolvedOutputPath
|
||||||
Ensure-Directory -Path $filesRootPath
|
Ensure-Directory -Path $filesRootPath
|
||||||
Ensure-Directory -Path $listsRootPath
|
Ensure-Directory -Path $listsRootPath
|
||||||
@@ -1383,7 +1604,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($list in $lists) {
|
foreach ($list in $lists) {
|
||||||
Export-SPList -Web $web -List $list -ListsRootPath $listsRootPath
|
Export-SPList -Web $web -List $list -ListsRootPath $listsRootPath -ManifestPath $manifestPath
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($documentLibraries.Length -eq 0 -and $lists.Length -eq 0) {
|
if ($documentLibraries.Length -eq 0 -and $lists.Length -eq 0) {
|
||||||
@@ -1393,13 +1614,6 @@ try {
|
|||||||
|
|
||||||
Write-Host ("Export abgeschlossen. Ausgabe: {0}" -f $resolvedOutputPath)
|
Write-Host ("Export abgeschlossen. Ausgabe: {0}" -f $resolvedOutputPath)
|
||||||
|
|
||||||
$importConfigurationProvided =
|
|
||||||
(-not [string]::IsNullOrWhiteSpace($TargetWebUrl)) -or
|
|
||||||
(-not [string]::IsNullOrWhiteSpace($MappingCsvPath)) -or
|
|
||||||
$ImportFiles -or
|
|
||||||
$ImportLists -or
|
|
||||||
$OverwriteFiles
|
|
||||||
|
|
||||||
if ($ExportOnly) {
|
if ($ExportOnly) {
|
||||||
Write-Host "ExportOnly ist gesetzt. Import wird uebersprungen."
|
Write-Host "ExportOnly ist gesetzt. Import wird uebersprungen."
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user