Skip to content

Instantly share code, notes, and snippets.

@FH-Inway
Created April 8, 2025 16:32
Show Gist options
  • Select an option

  • Save FH-Inway/5fe4a82a9bd42775a1149c2ffe068b11 to your computer and use it in GitHub Desktop.

Select an option

Save FH-Inway/5fe4a82a9bd42775a1149c2ffe068b11 to your computer and use it in GitHub Desktop.
Reassemble files created by Export-D365SecurityDetails.ps1
<#
.SYNOPSIS
Reverses the Export-D365SecurityDetails process by merging XML files back into a base XML structure.
.DESCRIPTION
This script takes a base XML file and merges the contents of XML files from specific folders into the appropriate nodes.
.PARAMETER BaseFilePath
Path to the base XML file.
.PARAMETER InputDirectory
Path to the folder containing subfolders with XML files to merge.
.PARAMETER OutputFilePath
Path to save the resulting merged XML file.
.EXAMPLE
PS C:\> Import-D365SecurityDetails -BaseFilePath C:\Temp\SecurityDatabaseCustomizations-Base.xml `
-InputDirectory C:\Temp\SecurityExtraction `
-OutputFilePath C:\Temp\SecurityDatabaseCustomizations-Merged.xml
This will merge the XML files from the input directory into the base XML file and save the result.
#>
function Import-D365SecurityDetails {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$BaseFilePath,
[Parameter(Mandatory = $true)]
[string]$InputDirectory,
[Parameter(Mandatory = $true)]
[string]$OutputFilePath
)
# Load the base XML file
[xml]$baseXml = Get-Content -Path $BaseFilePath
# Create an XmlNamespaceManager for handling namespaces
$namespaceManager = New-Object System.Xml.XmlNamespaceManager($baseXml.NameTable)
$namespaceManager.AddNamespace("ns", "http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.AX.Security.Management")
$namespaceManager.AddNamespace("i", "http://www.w3.org/2001/XMLSchema-instance")
# Define the mapping of folders to XML nodes
$folderToNodeMap = @{
"AxSecurityPrivilegeCustomized" = "//ns:BaseRepositoryCustomizations[@i:type='RepositoryCustomizationsOfAxSecurityPrivilegeNcCATIYq']/ns:_x003C_CustomizedObjectList_x003E_k__BackingField"
"AxSecurityRoleNew" = "//ns:BaseRepositoryCustomizations[@i:type='RepositoryCustomizationsOfAxSecurityRoleNcCATIYq']/ns:_x003C_NewObjectList_x003E_k__BackingField"
"AxSecurityDutyCustomized" = "//ns:BaseRepositoryCustomizations[@i:type='RepositoryCustomizationsOfAxSecurityDutyNcCATIYq']/ns:_x003C_CustomizedObjectList_x003E_k__BackingField"
"AxSecurityDutyNew" = "//ns:BaseRepositoryCustomizations[@i:type='RepositoryCustomizationsOfAxSecurityDutyNcCATIYq']/ns:_x003C_NewObjectList_x003E_k__BackingField"
"AxSecurityPrivilegeNew" = "//ns:BaseRepositoryCustomizations[@i:type='RepositoryCustomizationsOfAxSecurityPrivilegeNcCATIYq']/ns:_x003C_NewObjectList_x003E_k__BackingField"
"AxSecurityRoleCustomized" = "//ns:BaseRepositoryCustomizations[@i:type='RepositoryCustomizationsOfAxSecurityRoleNcCATIYq']/ns:_x003C_CustomizedObjectList_x003E_k__BackingField"
}
# Loop through each folder and merge its XML files into the corresponding node
foreach ($folder in $folderToNodeMap.Keys) {
$nodePath = $folderToNodeMap[$folder]
$targetNode = $baseXml.SelectSingleNode($nodePath, $namespaceManager)
if (-not $targetNode) {
Write-Warning "Node not found for folder: $folder"
continue
}
$folderPath = Join-Path -Path $InputDirectory -ChildPath $folder
if (-not (Test-Path -Path $folderPath)) {
Write-Warning "Folder not found: $folderPath"
continue
}
# Process each XML file in the folder
Get-ChildItem -Path $folderPath -Filter *.xml | ForEach-Object {
[xml]$fileXml = Get-Content -Path $_.FullName
$importedNode = $baseXml.ImportNode($fileXml.DocumentElement, $true)
$targetNode.AppendChild($importedNode) | Out-Null
}
}
# Save the merged XML to the output file
$baseXml.Save($OutputFilePath)
Write-Host "Merged XML saved to: $OutputFilePath"
}
<SecurityCustomizationData
xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.AX.Security.Management"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<_x003C_CustomizationsForTypeList_x003E_k__BackingField>
<BaseRepositoryCustomizations i:type="RepositoryCustomizationsOfAxSecurityRoleNcCATIYq">
<_x003C_CustomizedObjectList_x003E_k__BackingField />
<_x003C_DisabledObjectSet_x003E_k__BackingField
xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<_x003C_NewObjectList_x003E_k__BackingField></_x003C_NewObjectList_x003E_k__BackingField>
</BaseRepositoryCustomizations>
<BaseRepositoryCustomizations i:type="RepositoryCustomizationsOfAxSecurityDutyNcCATIYq">
<_x003C_CustomizedObjectList_x003E_k__BackingField />
<_x003C_DisabledObjectSet_x003E_k__BackingField
xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<_x003C_NewObjectList_x003E_k__BackingField />
</BaseRepositoryCustomizations>
<BaseRepositoryCustomizations i:type="RepositoryCustomizationsOfAxSecurityPrivilegeNcCATIYq">
<_x003C_CustomizedObjectList_x003E_k__BackingField></_x003C_CustomizedObjectList_x003E_k__BackingField>
<_x003C_DisabledObjectSet_x003E_k__BackingField
xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<_x003C_NewObjectList_x003E_k__BackingField />
</BaseRepositoryCustomizations>
</_x003C_CustomizationsForTypeList_x003E_k__BackingField>
</SecurityCustomizationData>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment