Add column mapping defaults functionality and example JSON file
This commit is contained in:
@@ -54,6 +54,7 @@ class SettingsManager {
|
||||
LastTargetUrl = ""
|
||||
LastOutputPath = (Join-Path -Path (Get-Location).Path -ChildPath "SPMigrationOutput")
|
||||
LastMappingTablePath = ""
|
||||
LastColumnDefaultsPath = ""
|
||||
}
|
||||
|
||||
foreach ($key in $defaults.Keys) {
|
||||
@@ -797,6 +798,14 @@ $script:CurrentMappingMeta = [ordered]@{
|
||||
GeneratedAtUtc = ""
|
||||
SourceWebUrl = ""
|
||||
}
|
||||
$script:IsMigrationRunning = $false
|
||||
$script:MigrationPowerShell = $null
|
||||
$script:MigrationAsyncResult = $null
|
||||
$script:MigrationOutput = $null
|
||||
$script:MigrationTimer = $null
|
||||
$script:MigrationStreamPositions = @{}
|
||||
$script:MigrationCompletedHandler = $null
|
||||
$script:MigrationActionLabel = ""
|
||||
|
||||
function Get-ObjectPropertyValue {
|
||||
param(
|
||||
@@ -872,7 +881,6 @@ function Write-UILog {
|
||||
$script:txtLog.AppendText($line)
|
||||
$script:txtLog.SelectionStart = $script:txtLog.TextLength
|
||||
$script:txtLog.ScrollToCaret()
|
||||
[System.Windows.Forms.Application]::DoEvents()
|
||||
}
|
||||
|
||||
switch ($Level) {
|
||||
@@ -1001,38 +1009,229 @@ function Convert-RecordToLogText {
|
||||
return [string]$Record
|
||||
}
|
||||
|
||||
function Set-MigrationUiBusy {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[bool]$IsBusy
|
||||
)
|
||||
|
||||
$script:IsMigrationRunning = $IsBusy
|
||||
|
||||
if ($null -ne $script:MainForm) {
|
||||
$script:MainForm.UseWaitCursor = $IsBusy
|
||||
}
|
||||
|
||||
$controlNames = @(
|
||||
"btnRunExport",
|
||||
"btnRunImport",
|
||||
"btnLoadContainers",
|
||||
"btnLoadMapping",
|
||||
"btnSaveMappingGlobal",
|
||||
"btnBrowseOutputPath",
|
||||
"btnSelectAllContainers",
|
||||
"btnClearContainerSelection",
|
||||
"btnLoadColumnDefaults",
|
||||
"btnApplyColumnDefaults",
|
||||
"btnSaveColumnDefaults"
|
||||
)
|
||||
|
||||
foreach ($controlName in $controlNames) {
|
||||
$variable = Get-Variable -Name $controlName -Scope Script -ErrorAction SilentlyContinue
|
||||
if ($null -eq $variable -or $null -eq $variable.Value) {
|
||||
continue
|
||||
}
|
||||
|
||||
$variable.Value.Enabled = -not $IsBusy
|
||||
}
|
||||
}
|
||||
|
||||
function Reset-MigrationStreamPositions {
|
||||
$script:MigrationStreamPositions = @{
|
||||
Output = 0
|
||||
Error = 0
|
||||
Warning = 0
|
||||
Verbose = 0
|
||||
Debug = 0
|
||||
Information = 0
|
||||
}
|
||||
}
|
||||
|
||||
function Write-NewPowerShellRecords {
|
||||
param(
|
||||
$Collection,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$PositionKey,
|
||||
|
||||
[ValidateSet("INFO", "WARN", "ERROR")]
|
||||
[string]$Level = "INFO"
|
||||
)
|
||||
|
||||
if ($null -eq $Collection -or -not $script:MigrationStreamPositions.ContainsKey($PositionKey)) {
|
||||
return
|
||||
}
|
||||
|
||||
while ($script:MigrationStreamPositions[$PositionKey] -lt $Collection.Count) {
|
||||
$index = [int]$script:MigrationStreamPositions[$PositionKey]
|
||||
$script:MigrationStreamPositions[$PositionKey] = $index + 1
|
||||
|
||||
try {
|
||||
$record = $Collection[$index]
|
||||
}
|
||||
catch {
|
||||
return
|
||||
}
|
||||
|
||||
$text = Convert-RecordToLogText -Record $record
|
||||
if (-not [string]::IsNullOrWhiteSpace($text)) {
|
||||
Write-UILog -Message $text -Level $Level
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Write-NewMigrationPowerShellRecords {
|
||||
if ($null -eq $script:MigrationPowerShell) {
|
||||
return
|
||||
}
|
||||
|
||||
Write-NewPowerShellRecords -Collection $script:MigrationOutput -PositionKey "Output" -Level "INFO"
|
||||
Write-NewPowerShellRecords -Collection $script:MigrationPowerShell.Streams.Warning -PositionKey "Warning" -Level "WARN"
|
||||
Write-NewPowerShellRecords -Collection $script:MigrationPowerShell.Streams.Error -PositionKey "Error" -Level "ERROR"
|
||||
Write-NewPowerShellRecords -Collection $script:MigrationPowerShell.Streams.Verbose -PositionKey "Verbose" -Level "INFO"
|
||||
Write-NewPowerShellRecords -Collection $script:MigrationPowerShell.Streams.Debug -PositionKey "Debug" -Level "INFO"
|
||||
Write-NewPowerShellRecords -Collection $script:MigrationPowerShell.Streams.Information -PositionKey "Information" -Level "INFO"
|
||||
}
|
||||
|
||||
function Clear-MigrationRunState {
|
||||
if ($null -ne $script:MigrationPowerShell) {
|
||||
$script:MigrationPowerShell.Dispose()
|
||||
}
|
||||
|
||||
if ($null -ne $script:MigrationOutput) {
|
||||
try {
|
||||
$script:MigrationOutput.Dispose()
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
|
||||
$script:MigrationPowerShell = $null
|
||||
$script:MigrationAsyncResult = $null
|
||||
$script:MigrationOutput = $null
|
||||
$script:MigrationCompletedHandler = $null
|
||||
$script:MigrationActionLabel = ""
|
||||
Reset-MigrationStreamPositions
|
||||
}
|
||||
|
||||
function Complete-MigrationScriptAsync {
|
||||
if ($null -eq $script:MigrationPowerShell -or $null -eq $script:MigrationAsyncResult) {
|
||||
return
|
||||
}
|
||||
|
||||
$actionLabel = $script:MigrationActionLabel
|
||||
$completedHandler = $script:MigrationCompletedHandler
|
||||
$success = $false
|
||||
$errorMessage = $null
|
||||
|
||||
Write-NewMigrationPowerShellRecords
|
||||
|
||||
try {
|
||||
[void]$script:MigrationPowerShell.EndInvoke($script:MigrationAsyncResult)
|
||||
Write-NewMigrationPowerShellRecords
|
||||
$success = $true
|
||||
}
|
||||
catch {
|
||||
Write-NewMigrationPowerShellRecords
|
||||
$errorMessage = $_.Exception.Message
|
||||
Write-UILog -Message $errorMessage -Level "ERROR"
|
||||
}
|
||||
finally {
|
||||
Clear-MigrationRunState
|
||||
Set-MigrationUiBusy -IsBusy $false
|
||||
}
|
||||
|
||||
if ($success) {
|
||||
Write-UILog -Message ("{0} abgeschlossen." -f $actionLabel)
|
||||
|
||||
if ($null -ne $completedHandler) {
|
||||
try {
|
||||
& $completedHandler
|
||||
}
|
||||
catch {
|
||||
Write-UILog -Message $_.Exception.Message -Level "ERROR"
|
||||
Show-UiMessage -Message $_.Exception.Message -Caption ("{0} abgeschlossen, Nachbereitung fehlgeschlagen" -f $actionLabel) -Icon ([System.Windows.Forms.MessageBoxIcon]::Warning)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Show-UiMessage -Message $errorMessage -Caption ("{0} fehlgeschlagen" -f $actionLabel) -Icon ([System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
}
|
||||
|
||||
function Ensure-MigrationTimer {
|
||||
if ($null -ne $script:MigrationTimer) {
|
||||
return
|
||||
}
|
||||
|
||||
$script:MigrationTimer = New-Object System.Windows.Forms.Timer
|
||||
$script:MigrationTimer.Interval = 250
|
||||
$script:MigrationTimer.Add_Tick({
|
||||
Write-NewMigrationPowerShellRecords
|
||||
|
||||
if ($null -eq $script:MigrationAsyncResult -or -not $script:MigrationAsyncResult.IsCompleted) {
|
||||
return
|
||||
}
|
||||
|
||||
$script:MigrationTimer.Stop()
|
||||
Complete-MigrationScriptAsync
|
||||
})
|
||||
}
|
||||
|
||||
function Invoke-MigrationScript {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[hashtable]$Parameters,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$ActionLabel
|
||||
[string]$ActionLabel,
|
||||
|
||||
[scriptblock]$OnCompleted = $null
|
||||
)
|
||||
|
||||
if (-not (Test-Path -LiteralPath $script:MigrationScriptPath)) {
|
||||
throw ("Start-SPMigration.ps1 nicht gefunden: {0}" -f $script:MigrationScriptPath)
|
||||
}
|
||||
|
||||
$script:MainForm.UseWaitCursor = $true
|
||||
[System.Windows.Forms.Application]::DoEvents()
|
||||
if ($script:IsMigrationRunning) {
|
||||
throw "Es laeuft bereits ein Export oder Import. Bitte warten, bis der aktuelle Vorgang abgeschlossen ist."
|
||||
}
|
||||
|
||||
Reset-MigrationStreamPositions
|
||||
$script:MigrationPowerShell = [powershell]::Create()
|
||||
$script:MigrationOutput = [System.Management.Automation.PSDataCollection[psobject]]::new()
|
||||
$script:MigrationCompletedHandler = $OnCompleted
|
||||
$script:MigrationActionLabel = $ActionLabel
|
||||
|
||||
try {
|
||||
[void]$script:MigrationPowerShell.AddCommand($script:MigrationScriptPath)
|
||||
[void]$script:MigrationPowerShell.AddParameters($Parameters)
|
||||
|
||||
Set-MigrationUiBusy -IsBusy $true
|
||||
Write-UILog -Message ("Starte {0}..." -f $ActionLabel)
|
||||
& $script:MigrationScriptPath @Parameters *>&1 | ForEach-Object {
|
||||
$text = Convert-RecordToLogText -Record $_
|
||||
if (-not [string]::IsNullOrWhiteSpace($text)) {
|
||||
Write-UILog -Message $text
|
||||
}
|
||||
}
|
||||
Write-UILog -Message ("{0} abgeschlossen." -f $ActionLabel)
|
||||
|
||||
$inputCollection = [System.Management.Automation.PSDataCollection[psobject]]::new()
|
||||
$inputCollection.Complete()
|
||||
$script:MigrationAsyncResult = $script:MigrationPowerShell.BeginInvoke($inputCollection, $script:MigrationOutput)
|
||||
|
||||
Ensure-MigrationTimer
|
||||
$script:MigrationTimer.Start()
|
||||
}
|
||||
finally {
|
||||
$script:MainForm.UseWaitCursor = $false
|
||||
[System.Windows.Forms.Application]::DoEvents()
|
||||
catch {
|
||||
Clear-MigrationRunState
|
||||
Set-MigrationUiBusy -IsBusy $false
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Get-SourceContainers {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
@@ -1465,7 +1664,7 @@ function Convert-DataTableToObjects {
|
||||
|
||||
foreach ($columnDefinition in $Schema) {
|
||||
$value = $row[$columnDefinition.Name]
|
||||
if ($value -eq [System.DBNull]::Value) {
|
||||
if ($value -is [System.DBNull]) {
|
||||
$value = $null
|
||||
}
|
||||
|
||||
@@ -1647,6 +1846,305 @@ function Save-MappingTableToPath {
|
||||
Write-UILog -Message ("MappingTable gespeichert: {0}" -f $resolvedPath)
|
||||
}
|
||||
|
||||
function Test-ObjectHasProperty {
|
||||
param(
|
||||
$Object,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$PropertyName
|
||||
)
|
||||
|
||||
if ($null -eq $Object) {
|
||||
return $false
|
||||
}
|
||||
|
||||
if ($Object -is [System.Collections.IDictionary]) {
|
||||
return $Object.Contains($PropertyName)
|
||||
}
|
||||
|
||||
return $null -ne $Object.PSObject.Properties[$PropertyName]
|
||||
}
|
||||
|
||||
function Get-ColumnDefaultRulesFromObject {
|
||||
param(
|
||||
$Template
|
||||
)
|
||||
|
||||
if ($null -eq $Template) {
|
||||
return @()
|
||||
}
|
||||
|
||||
$rules = Get-ObjectPropertyValue -Object $Template -PropertyName "Rules" -DefaultValue $null
|
||||
if ($null -ne $rules) {
|
||||
return @($rules)
|
||||
}
|
||||
|
||||
$rules = Get-ObjectPropertyValue -Object $Template -PropertyName "ColumnMappings" -DefaultValue $null
|
||||
if ($null -ne $rules) {
|
||||
return @($rules)
|
||||
}
|
||||
|
||||
$metadataColumnMappings = Get-ObjectPropertyValue -Object $Template -PropertyName "MetadataColumnMappings" -DefaultValue $null
|
||||
if ($null -ne $metadataColumnMappings) {
|
||||
return @(
|
||||
@(Get-ObjectPropertyValue -Object $metadataColumnMappings -PropertyName "SystemColumns" -DefaultValue @()) +
|
||||
@(Get-ObjectPropertyValue -Object $metadataColumnMappings -PropertyName "CustomColumns" -DefaultValue @())
|
||||
)
|
||||
}
|
||||
|
||||
return @()
|
||||
}
|
||||
|
||||
function Get-ColumnDefaultRuleMatchPriority {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
$Rule,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[System.Data.DataRow]$Row
|
||||
)
|
||||
|
||||
$ruleSourceInternalName = [string](Get-ObjectPropertyValue -Object $Rule -PropertyName "SourceInternalName")
|
||||
if ([string]::IsNullOrWhiteSpace($ruleSourceInternalName)) {
|
||||
return -1
|
||||
}
|
||||
|
||||
$rowSourceInternalName = [string]$Row["SourceInternalName"]
|
||||
$rowCanonicalInternalName = [string]$Row["SourceCanonicalInternalName"]
|
||||
if ($ruleSourceInternalName -ine $rowSourceInternalName -and $ruleSourceInternalName -ine $rowCanonicalInternalName) {
|
||||
return -1
|
||||
}
|
||||
|
||||
$ruleObjectType = [string](Get-ObjectPropertyValue -Object $Rule -PropertyName "ObjectType" -DefaultValue "*")
|
||||
$ruleContainerSourceTitle = [string](Get-ObjectPropertyValue -Object $Rule -PropertyName "ContainerSourceTitle" -DefaultValue "*")
|
||||
$rowObjectType = [string]$Row["ObjectType"]
|
||||
$rowContainerSourceTitle = [string]$Row["ContainerSourceTitle"]
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($ruleObjectType)) {
|
||||
$ruleObjectType = "*"
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($ruleContainerSourceTitle)) {
|
||||
$ruleContainerSourceTitle = "*"
|
||||
}
|
||||
|
||||
if ($ruleObjectType -ne "*" -and $ruleObjectType -ine $rowObjectType) {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ($ruleContainerSourceTitle -ne "*" -and $ruleContainerSourceTitle -ine $rowContainerSourceTitle) {
|
||||
return -1
|
||||
}
|
||||
|
||||
$priority = 0
|
||||
if ($ruleObjectType -ne "*") {
|
||||
$priority += 2
|
||||
}
|
||||
|
||||
if ($ruleContainerSourceTitle -ne "*") {
|
||||
$priority += 1
|
||||
}
|
||||
|
||||
return $priority
|
||||
}
|
||||
|
||||
function Get-BestColumnDefaultRule {
|
||||
param(
|
||||
[object[]]$Rules = @(),
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[System.Data.DataRow]$Row
|
||||
)
|
||||
|
||||
$bestRule = $null
|
||||
$bestPriority = -1
|
||||
|
||||
foreach ($rule in @($Rules)) {
|
||||
$priority = Get-ColumnDefaultRuleMatchPriority -Rule $rule -Row $Row
|
||||
if ($priority -gt $bestPriority) {
|
||||
$bestPriority = $priority
|
||||
$bestRule = $rule
|
||||
}
|
||||
}
|
||||
|
||||
return $bestRule
|
||||
}
|
||||
|
||||
function Apply-ColumnDefaultRulesToTable {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[System.Data.DataTable]$Table,
|
||||
|
||||
[object[]]$Rules = @()
|
||||
)
|
||||
|
||||
$updatedCount = 0
|
||||
|
||||
foreach ($row in $Table.Rows) {
|
||||
$rule = Get-BestColumnDefaultRule -Rules $Rules -Row $row
|
||||
if ($null -eq $rule) {
|
||||
continue
|
||||
}
|
||||
|
||||
$rowWasUpdated = $false
|
||||
|
||||
if (Test-ObjectHasProperty -Object $rule -PropertyName "TargetInternalName") {
|
||||
$targetInternalName = [string](Get-ObjectPropertyValue -Object $rule -PropertyName "TargetInternalName" -DefaultValue "")
|
||||
if (-not [string]::IsNullOrWhiteSpace($targetInternalName)) {
|
||||
$row["TargetInternalName"] = $targetInternalName
|
||||
$rowWasUpdated = $true
|
||||
}
|
||||
}
|
||||
|
||||
if (Test-ObjectHasProperty -Object $rule -PropertyName "ImportSupported") {
|
||||
$row["ImportSupported"] = [bool](Get-ObjectPropertyValue -Object $rule -PropertyName "ImportSupported" -DefaultValue $false)
|
||||
$rowWasUpdated = $true
|
||||
}
|
||||
|
||||
if ($rowWasUpdated) {
|
||||
$updatedCount++
|
||||
}
|
||||
}
|
||||
|
||||
return $updatedCount
|
||||
}
|
||||
|
||||
function Apply-ColumnDefaultsFromPath {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($Path)) {
|
||||
throw "Bitte einen ColumnDefaults-Pfad angeben."
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $Path)) {
|
||||
throw ("ColumnDefaults nicht gefunden: {0}" -f $Path)
|
||||
}
|
||||
|
||||
if ([System.IO.Path]::GetExtension($Path) -ine ".json") {
|
||||
throw "ColumnDefaults muessen als JSON-Datei vorliegen."
|
||||
}
|
||||
|
||||
$template = Get-Content -LiteralPath $Path -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
$rules = @(Get-ColumnDefaultRulesFromObject -Template $template)
|
||||
if ($rules.Count -eq 0) {
|
||||
throw "ColumnDefaults enthalten keine Rules."
|
||||
}
|
||||
|
||||
$systemCount = Apply-ColumnDefaultRulesToTable -Table $script:SystemColumnsTable -Rules $rules
|
||||
$customCount = Apply-ColumnDefaultRulesToTable -Table $script:CustomColumnsTable -Rules $rules
|
||||
$script:txtColumnDefaultsPath.Text = (Get-FullPathSafe -Path $Path)
|
||||
|
||||
Write-UILog -Message ("ColumnDefaults angewendet: {0} System Columns, {1} Custom Columns." -f $systemCount, $customCount)
|
||||
}
|
||||
|
||||
function New-ColumnDefaultRuleObject {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
$RowObject,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[bool]$UseWildcardContainer
|
||||
)
|
||||
|
||||
$containerSourceTitle = if ($UseWildcardContainer) { "*" } else { [string]$RowObject.ContainerSourceTitle }
|
||||
|
||||
return [PSCustomObject]@{
|
||||
ObjectType = [string]$RowObject.ObjectType
|
||||
ContainerSourceTitle = $containerSourceTitle
|
||||
SourceInternalName = [string]$RowObject.SourceInternalName
|
||||
SourceCanonicalInternalName = [string]$RowObject.SourceCanonicalInternalName
|
||||
TargetInternalName = [string]$RowObject.TargetInternalName
|
||||
ImportSupported = [bool]$RowObject.ImportSupported
|
||||
DisplayName = [string]$RowObject.DisplayName
|
||||
TypeAsString = [string]$RowObject.TypeAsString
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ColumnDefaultRowsForExport {
|
||||
$rows = @(
|
||||
@(Convert-DataTableToObjects -Table $script:SystemColumnsTable -Schema $script:GridSchemas.SystemColumns) +
|
||||
@(Convert-DataTableToObjects -Table $script:CustomColumnsTable -Schema $script:GridSchemas.CustomColumns)
|
||||
)
|
||||
|
||||
return @($rows | Where-Object { -not [string]::IsNullOrWhiteSpace([string]$_.SourceInternalName) })
|
||||
}
|
||||
|
||||
function New-ColumnDefaultsTemplateFromUi {
|
||||
$rows = @(Get-ColumnDefaultRowsForExport)
|
||||
$groups = @{}
|
||||
|
||||
foreach ($row in $rows) {
|
||||
$key = ("{0}|{1}" -f ([string]$row.ObjectType).Trim(), ([string]$row.SourceInternalName).Trim()).ToLowerInvariant()
|
||||
if (-not $groups.ContainsKey($key)) {
|
||||
$groups[$key] = New-Object System.Collections.ArrayList
|
||||
}
|
||||
|
||||
[void]$groups[$key].Add($row)
|
||||
}
|
||||
|
||||
$rules = @()
|
||||
|
||||
foreach ($key in $groups.Keys) {
|
||||
$groupRows = @($groups[$key])
|
||||
$targetKeys = @(
|
||||
$groupRows | ForEach-Object {
|
||||
"{0}|{1}" -f ([string]$_.TargetInternalName).Trim(), ([bool]$_.ImportSupported)
|
||||
} | Sort-Object -Unique
|
||||
)
|
||||
|
||||
if ($targetKeys.Count -le 1) {
|
||||
$rules += New-ColumnDefaultRuleObject -RowObject $groupRows[0] -UseWildcardContainer $true
|
||||
}
|
||||
else {
|
||||
foreach ($row in $groupRows) {
|
||||
$rules += New-ColumnDefaultRuleObject -RowObject $row -UseWildcardContainer $false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
SchemaVersion = 1
|
||||
TemplateType = "ColumnMappings"
|
||||
GeneratedAtUtc = [System.DateTime]::UtcNow.ToString("o")
|
||||
Rules = @($rules | Sort-Object -Property ObjectType, ContainerSourceTitle, SourceInternalName)
|
||||
}
|
||||
}
|
||||
|
||||
function Save-ColumnDefaultsToPath {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($Path)) {
|
||||
throw "Bitte einen Pfad fuer ColumnDefaults angeben."
|
||||
}
|
||||
|
||||
$resolvedPath = Get-FullPathSafe -Path $Path
|
||||
Ensure-ParentDirectory -Path $resolvedPath
|
||||
$template = New-ColumnDefaultsTemplateFromUi
|
||||
$json = $template | ConvertTo-Json -Depth 10
|
||||
[System.IO.File]::WriteAllText($resolvedPath, $json, [System.Text.Encoding]::UTF8)
|
||||
$script:txtColumnDefaultsPath.Text = $resolvedPath
|
||||
Write-UILog -Message ("ColumnDefaults gespeichert: {0}" -f $resolvedPath)
|
||||
}
|
||||
|
||||
function Apply-ColumnDefaultsIfAvailable {
|
||||
$path = [string]$script:txtColumnDefaultsPath.Text
|
||||
if ([string]::IsNullOrWhiteSpace($path)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $path)) {
|
||||
Write-UILog -Message ("ColumnDefaults nicht gefunden und wurden nicht angewendet: {0}" -f $path) -Level "WARN"
|
||||
return
|
||||
}
|
||||
|
||||
Apply-ColumnDefaultsFromPath -Path $path
|
||||
}
|
||||
function Save-UiSettings {
|
||||
$script:SettingsManager.Set("WindowWidth", $script:MainForm.Width)
|
||||
$script:SettingsManager.Set("WindowHeight", $script:MainForm.Height)
|
||||
@@ -1654,6 +2152,7 @@ function Save-UiSettings {
|
||||
$script:SettingsManager.Set("LastTargetUrl", [string]$script:txtTargetUrl.Text)
|
||||
$script:SettingsManager.Set("LastOutputPath", [string]$script:txtOutputPath.Text)
|
||||
$script:SettingsManager.Set("LastMappingTablePath", [string]$script:txtMappingPath.Text)
|
||||
$script:SettingsManager.Set("LastColumnDefaultsPath", [string]$script:txtColumnDefaultsPath.Text)
|
||||
}
|
||||
|
||||
function Load-UiSettings {
|
||||
@@ -1661,6 +2160,7 @@ function Load-UiSettings {
|
||||
$script:txtTargetUrl.Text = [string]$script:SettingsManager.Get("LastTargetUrl", "")
|
||||
$script:txtOutputPath.Text = [string]$script:SettingsManager.Get("LastOutputPath", (Join-Path -Path (Get-Location).Path -ChildPath "SPMigrationOutput"))
|
||||
$script:txtMappingPath.Text = [string]$script:SettingsManager.Get("LastMappingTablePath", "")
|
||||
$script:txtColumnDefaultsPath.Text = [string]$script:SettingsManager.Get("LastColumnDefaultsPath", "")
|
||||
$script:MainForm.Width = [int]$script:SettingsManager.Get("WindowWidth", 1400)
|
||||
$script:MainForm.Height = [int]$script:SettingsManager.Get("WindowHeight", 940)
|
||||
Sync-MappingPathWithOutputPath -Force
|
||||
@@ -1692,7 +2192,6 @@ function Invoke-LoadContainers {
|
||||
}
|
||||
|
||||
$script:MainForm.UseWaitCursor = $true
|
||||
[System.Windows.Forms.Application]::DoEvents()
|
||||
|
||||
try {
|
||||
Write-UILog -Message ("Lese Listen und Bibliotheken aus: {0}" -f $sourceUrl)
|
||||
@@ -1706,7 +2205,6 @@ function Invoke-LoadContainers {
|
||||
}
|
||||
finally {
|
||||
$script:MainForm.UseWaitCursor = $false
|
||||
[System.Windows.Forms.Application]::DoEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1749,13 +2247,17 @@ function Invoke-ExportFromGui {
|
||||
$parameters.IncludeHiddenLists = $true
|
||||
}
|
||||
|
||||
Invoke-MigrationScript -Parameters $parameters -ActionLabel "Export"
|
||||
|
||||
$mappingPath = Join-Path -Path $outputPath -ChildPath "MappingTable.json"
|
||||
if (Test-Path -LiteralPath $mappingPath) {
|
||||
Load-MappingTableFromPath -Path $mappingPath
|
||||
$script:MainTabControl.SelectedTab = $script:tabMapping
|
||||
}
|
||||
$onCompleted = {
|
||||
if (Test-Path -LiteralPath $mappingPath) {
|
||||
Load-MappingTableFromPath -Path $mappingPath
|
||||
Apply-ColumnDefaultsIfAvailable
|
||||
Save-MappingTableToPath -Path $mappingPath
|
||||
$script:MainTabControl.SelectedTab = $script:tabMapping
|
||||
}
|
||||
}.GetNewClosure()
|
||||
|
||||
Invoke-MigrationScript -Parameters $parameters -ActionLabel "Export" -OnCompleted $onCompleted
|
||||
}
|
||||
catch {
|
||||
Write-UILog -Message $_.Exception.Message -Level "ERROR"
|
||||
@@ -1823,19 +2325,21 @@ $mainLayout = New-Object System.Windows.Forms.TableLayoutPanel
|
||||
$mainLayout.Dock = [System.Windows.Forms.DockStyle]::Fill
|
||||
$mainLayout.RowCount = 3
|
||||
$mainLayout.ColumnCount = 1
|
||||
[void]$mainLayout.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 110)))
|
||||
[void]$mainLayout.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 146)))
|
||||
[void]$mainLayout.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Percent, 100)))
|
||||
[void]$mainLayout.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 230)))
|
||||
|
||||
$workspaceGroup = ([GroupBoxBuilder]::new("Arbeitsbereich")).Build()
|
||||
$workspaceLayout = New-Object System.Windows.Forms.TableLayoutPanel
|
||||
$workspaceLayout.Dock = [System.Windows.Forms.DockStyle]::Fill
|
||||
$workspaceLayout.RowCount = 2
|
||||
$workspaceLayout.ColumnCount = 4
|
||||
$workspaceLayout.RowCount = 3
|
||||
$workspaceLayout.ColumnCount = 5
|
||||
[void]$workspaceLayout.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Absolute, 105)))
|
||||
[void]$workspaceLayout.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Percent, 100)))
|
||||
[void]$workspaceLayout.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Absolute, 110)))
|
||||
[void]$workspaceLayout.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Absolute, 110)))
|
||||
[void]$workspaceLayout.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Absolute, 110)))
|
||||
[void]$workspaceLayout.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 36)))
|
||||
[void]$workspaceLayout.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 36)))
|
||||
[void]$workspaceLayout.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 36)))
|
||||
|
||||
@@ -1858,6 +2362,18 @@ $script:txtMappingPath.Margin = New-Object System.Windows.Forms.Padding(6)
|
||||
$btnLoadMapping = ([ButtonBuilder]::new("Laden...")).SetSize(95, 28).Build()
|
||||
$btnLoadMapping.Margin = New-Object System.Windows.Forms.Padding(6)
|
||||
|
||||
$lblColumnDefaultsPath = ([LabelBuilder]::new("ColumnDefaults")).SetTextAlign([System.Drawing.ContentAlignment]::MiddleLeft).Build()
|
||||
$lblColumnDefaultsPath.Dock = [System.Windows.Forms.DockStyle]::Fill
|
||||
$script:txtColumnDefaultsPath = New-Object System.Windows.Forms.TextBox
|
||||
$script:txtColumnDefaultsPath.Dock = [System.Windows.Forms.DockStyle]::Fill
|
||||
$script:txtColumnDefaultsPath.Margin = New-Object System.Windows.Forms.Padding(6)
|
||||
$btnApplyColumnDefaults = ([ButtonBuilder]::new("Anwenden")).SetSize(95, 28).Build()
|
||||
$btnApplyColumnDefaults.Margin = New-Object System.Windows.Forms.Padding(6)
|
||||
$btnLoadColumnDefaults = ([ButtonBuilder]::new("Laden...")).SetSize(95, 28).Build()
|
||||
$btnLoadColumnDefaults.Margin = New-Object System.Windows.Forms.Padding(6)
|
||||
$btnSaveColumnDefaults = ([ButtonBuilder]::new("Speichern")).SetSize(95, 28).Build()
|
||||
$btnSaveColumnDefaults.Margin = New-Object System.Windows.Forms.Padding(6)
|
||||
|
||||
[void]$workspaceLayout.Controls.Add($lblOutputPath, 0, 0)
|
||||
[void]$workspaceLayout.Controls.Add($script:txtOutputPath, 1, 0)
|
||||
[void]$workspaceLayout.Controls.Add($btnBrowseOutputPath, 2, 0)
|
||||
@@ -1865,6 +2381,11 @@ $btnLoadMapping.Margin = New-Object System.Windows.Forms.Padding(6)
|
||||
[void]$workspaceLayout.Controls.Add($lblMappingPath, 0, 1)
|
||||
[void]$workspaceLayout.Controls.Add($script:txtMappingPath, 1, 1)
|
||||
[void]$workspaceLayout.Controls.Add($btnLoadMapping, 2, 1)
|
||||
[void]$workspaceLayout.Controls.Add($lblColumnDefaultsPath, 0, 2)
|
||||
[void]$workspaceLayout.Controls.Add($script:txtColumnDefaultsPath, 1, 2)
|
||||
[void]$workspaceLayout.Controls.Add($btnApplyColumnDefaults, 2, 2)
|
||||
[void]$workspaceLayout.Controls.Add($btnLoadColumnDefaults, 3, 2)
|
||||
[void]$workspaceLayout.Controls.Add($btnSaveColumnDefaults, 4, 2)
|
||||
$workspaceGroup.Controls.Add($workspaceLayout)
|
||||
|
||||
$script:MainTabControl = ([TabControlBuilder]::new()).SetDock("Fill").Build()
|
||||
@@ -2139,6 +2660,58 @@ $btnLoadMapping.Add_Click({
|
||||
}
|
||||
})
|
||||
|
||||
$btnApplyColumnDefaults.Add_Click({
|
||||
try {
|
||||
Apply-ColumnDefaultsFromPath -Path ([string]$script:txtColumnDefaultsPath.Text)
|
||||
}
|
||||
catch {
|
||||
Write-UILog -Message $_.Exception.Message -Level "ERROR"
|
||||
Show-UiMessage -Message $_.Exception.Message -Caption "ColumnDefaults konnten nicht angewendet werden" -Icon ([System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
})
|
||||
|
||||
$btnLoadColumnDefaults.Add_Click({
|
||||
try {
|
||||
$dialog = [DialogBuilder]::OpenFile().SetTitle("ColumnDefaults laden").SetFilter("JSON (*.json)|*.json|Alle Dateien (*.*)|*.*").SetCheckFileExists($true)
|
||||
$initialDirectory = Get-ParentDirectorySafe -Path $script:txtColumnDefaultsPath.Text
|
||||
if ([string]::IsNullOrWhiteSpace($initialDirectory)) {
|
||||
$initialDirectory = Get-ParentDirectorySafe -Path $script:txtMappingPath.Text
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($initialDirectory)) {
|
||||
$initialDirectory = Get-ParentDirectorySafe -Path $script:txtOutputPath.Text
|
||||
}
|
||||
if (-not [string]::IsNullOrWhiteSpace($initialDirectory)) {
|
||||
$dialog.SetInitialDirectory($initialDirectory) | Out-Null
|
||||
}
|
||||
|
||||
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
|
||||
Apply-ColumnDefaultsFromPath -Path $dialog.GetPath()
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-UILog -Message $_.Exception.Message -Level "ERROR"
|
||||
Show-UiMessage -Message $_.Exception.Message -Caption "ColumnDefaults konnten nicht geladen werden" -Icon ([System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
})
|
||||
|
||||
$btnSaveColumnDefaults.Add_Click({
|
||||
try {
|
||||
$currentDefaultsPath = [string]$script:txtColumnDefaultsPath.Text
|
||||
$dialog = [DialogBuilder]::SaveFile().SetTitle("ColumnDefaults speichern").SetFilter("JSON (*.json)|*.json|Alle Dateien (*.*)|*.*").SetOverwritePrompt($true)
|
||||
if (-not [string]::IsNullOrWhiteSpace($currentDefaultsPath)) {
|
||||
$dialog.SetInitialDirectory((Get-ParentDirectorySafe -Path $currentDefaultsPath)) | Out-Null
|
||||
$dialog.SetFileName([System.IO.Path]::GetFileName($currentDefaultsPath)) | Out-Null
|
||||
}
|
||||
|
||||
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
|
||||
Save-ColumnDefaultsToPath -Path $dialog.GetPath()
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-UILog -Message $_.Exception.Message -Level "ERROR"
|
||||
Show-UiMessage -Message $_.Exception.Message -Caption "ColumnDefaults konnten nicht gespeichert werden" -Icon ([System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
})
|
||||
$script:tvContainers.Add_AfterCheck({
|
||||
param($sender, $e)
|
||||
|
||||
@@ -2185,6 +2758,14 @@ $script:MainForm.Add_Shown({
|
||||
})
|
||||
|
||||
$script:MainForm.Add_FormClosing({
|
||||
param($sender, $e)
|
||||
|
||||
if ($script:IsMigrationRunning) {
|
||||
$e.Cancel = $true
|
||||
Show-UiMessage -Message "Bitte warten, bis der laufende Export oder Import abgeschlossen ist." -Caption "Vorgang laeuft" -Icon ([System.Windows.Forms.MessageBoxIcon]::Warning)
|
||||
return
|
||||
}
|
||||
|
||||
Save-UiSettings
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user