Function Import-LegacyLabelXml { <# .SYNOPSIS Imports labels into the Security & Compliance Center from an export-xml of classic AIP labels. This import only applies to localization components of tags! .DESCRIPTION Imports labels into the Security & Compliance Center from an export-xml of classic AIP labels. This avoids having to manually update labels in multiple-language scenarios. This import only applies to localization components of tags! Settings will be merged into existing labels, if those already exist. Important: This command assumes you are already connected to the Office365 Security & Compliance Center! .PARAMETER Path Path to the XML file(s) to import. .PARAMETER Replace By default, keys for existing languages are not overwritten. Enabling this switch will instead overwrite those with the strings defined in the import xml. .EXAMPLE PS C:\> Get-ChildItem C:\export\*.xml | Import-LegacyLabelXml Imports all the xml files in C:\export, parses them for label DisplayNames and descriptions and uploads them into S&CC. #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('FullName')] [string[]] $Path, [switch] $Replace ) begin { #region Utility Functions function Write-LabelObject { [CmdletBinding()] param ( [string] $Name, [AllowNull()] [AllowEmptyString()] [string] $Parent, [string] $Identity, [string] $Language, [string] $Setting, [string] $Text, [string] $DefaultText, [Hashtable] $DataSet, [Hashtable] $Labels ) if (-not $DataSet[$Identity]) { $DataSet[$Identity] = [PSCustomObject]@{ Name = $Name Parent = $Parent Identity = $Identity ID = $Labels[$Identity].Guid ParentID = $(if ($Parent) { $Labels[$Parent].Guid } else { $null }) Description = @{ } DisplayName = @{ } } $DataSet[$Identity].$($Setting)['default'] = $DefaultText } $DataSet[$Identity].$($Setting)[$Language] = $Text } function Update-LocalizedLabel { [CmdletBinding()] param ( $DataObject, [Hashtable] $Labels, [bool] $Replace ) Write-Verbose "Updating $($DataObject.Identity)" $identity = $DataObject.ID if (-not $identity) { $identity = $Labels[$DataObject.Identity].Guid } $jsonData = $Labels[$DataObject.Identity].LocaleSettings | ConvertTo-Json $displayNameList = @{ } foreach ($entry in ($jsonData | Where-Object LocaleKey -eq "displayName").Settings) { $displayNameList[$entry.Key] = @{ Key = $entry.Key Value = $entry.Value } } foreach ($languageKey in $DataObject.DisplayName.Keys) { if (-not $Replace -and $displayNameList[$languageKey]) { continue } $displayNameList[$languageKey] = @{ Key = $languageKey Value = $DataObject.DisplayName[$languageKey] } } $displayNameObject = [PSCustomObject]@{ LocaleKey = 'DisplayName' Settings = @($displayNameList.Values | Write-Output) } Set-Label -Identity $identity -LocaleSettings (ConvertTo-Json $displayNameObject -Depth 3 -Compress) $tooltipList = @{ } foreach ($entry in ($jsonData | Where-Object LocaleKey -eq "tooltip").Settings) { $tooltipList[$entry.Key] = @{ Key = $entry.Key Value = $entry.Value } } foreach ($languageKey in $DataObject.Description.Keys) { if (-not $Replace -and $tooltipList[$languageKey]) { continue } $tooltipList[$languageKey] = @{ Key = $languageKey Value = $DataObject.Description[$languageKey] } } $tooltipObject = [PSCustomObject]@{ LocaleKey = 'Tooltip' Settings = @($tooltipList.Values | Write-Output) } Set-Label -Identity $identity -LocaleSettings (ConvertTo-Json $tooltipObject -Depth 3 -Compress) } function New-LocalizedLabel { [CmdletBinding()] param ( $DataObject, [Hashtable] $Labels ) Write-Verbose "Creating $($DataObject.Identity)" $parameters = @{ Name = [guid]::NewGuid() DisplayName = $DataObject.Name } if ($DataObject.ParentID) { $parameters['ParentID'] = $DataObject.ParentID } elseif ($DataObject.Parent) { $parameters['ParentID'] = $Labels[$DataObject.Parent].Guid } $newLabel = New-Label @parameters | Select-Object -Property Name, DisplayName, Guid, ParentID, LocaleSettings, Identity $newLabel.Identity = $DataObject.Identity $Labels[$newLabel.Identity] = $newLabel Update-LocalizedLabel -DataObject $DataObject -Labels $Labels -Replace $true } #endregion Utility Functions $dataSet = @{ } $labelBase = @{ } $labels = @{ } $labelData = Get-Label | Select-Object -Property Name, DisplayName, Guid, ParentID, LocaleSettings, Identity foreach ($label in $labelData) { $labelBase[$label.Guid] = $label } foreach ($label in $labelData) { $identity = $label.DisplayName if ($label.ParentID) { $identity = '{0}/{1}' -f $labelBase[$label.ParentID].DisplayName, $label.DisplayName } $labels[$identity] = $label } } process { foreach ($filePath in $Path) { Write-Verbose "Processing $filePath" #region Validation if (-not (Test-Path $filePath)) { Write-Warning "File does not exist: $filePath !" throw "File does not exist: $filePath !" } try { [xml]$xmlData = Get-Content -Path $filePath -ErrorAction Stop -Encoding utf8 } catch { Write-Warning "Input is not a legal XML file: $filePath !" throw } #endregion Validation #region Process File $language = $xmlData.Language.Id $localizationData = $xmlData.Language.LocItem | Where-Object ID -match '^labelGroups/Sensitivity/labels/.+/(DisplayName|Description)$' | Select-Object @{ Name = 'ID' Expression = { $_.ID.Replace("labelGroups/Sensitivity/labels/", "") } }, defaultText, LocalizedText foreach ($localDatum in $localizationData) { $parent = $null $identity = ($localDatum.ID -split "/")[-2] if (($localDatum.ID -split "/").Count -ge 4) { $parent = ($localDatum.ID -split "/")[-4] $identity = '{0}/{1}' -f $parent, $identity } $parameters = @{ Name = ($localDatum.ID -split "/")[-2] Parent = $parent Identity = $identity Language = $language Setting = ($localDatum.ID -split "/")[-1] Text = $localDatum.LocalizedText DefaultText = $localDatum.defaultText DataSet = $dataSet Labels = $labels } Write-LabelObject @parameters } #endregion Process File } } end { foreach ($labelObject in ($dataSet.Values | Where-Object Parent -eq "")) { if ($labelObject.ID) { Update-LocalizedLabel -DataObject $labelObject -Labels $labels -Replace $Replace.ToBool() } else { New-LocalizedLabel -DataObject $labelObject -Labels $labels } } foreach ($labelObject in ($dataSet.Values | Where-Object Parent -ne "")) { if ($labelObject.ID) { Update-LocalizedLabel -DataObject $labelObject -Labels $labels -Replace $Replace.ToBool() } else { New-LocalizedLabel -DataObject $labelObject -Labels $labels } } } }