Skip to content

✨ Add script to enable Trace Parser to show both system and custom metadata for UDE environments #892

@FH-Inway

Description

@FH-Inway

There is a common challenge when using Trace Parser locally for UDE environments: it only shows either system or custom metadata, not both at the same time. This forces users to repeatedly switch between folders using "File > select local metadata repo", which is inconvenient and slows down the workflow.

In https://www.yammer.com/dynamicsaxfeedbackprograms/threads/3407795405217792, @batetech describes the issue and shared a PowerShell script that creates a new folder (xxceTraceParserPackagesLocalDirectory) under %localappdata%\Microsoft\Dynamics365\RuntimeSymLinks\{yourConfig}\xxceTraceParserPackagesLocalDirectory using symbolic links to combine system and custom metadata. This allows Trace Parser to display the complete source code view for both, without duplicating data or using extra disk space.

The script is intended for local UDE environments. After running it, Trace Parser can be pointed to the new folder, and it will show both sets of code.

The script is to be integrated into d365fo.tools as a new command.

PowerShell script by @batetech

#Requires -RunAsAdministrator
<#
    This script will create Symbolic Links for UDE environments for use in TraceParse
    A folder will be created under "%localappdata%\Microsoft\Dynamics365\RuntimeSymLinks\{yourConfig}\xxceTraceParserPackagesLocalDirectory"
        which contains all PackagesLocalDirectory and custom metadata, so that Trace Parser can display the correct source code. 
    In Trace Parser, after running this script, go to "File > select local metadata repo" and select the new xxceTraceParserPackagesLocalDirectory folder.

Change history: 
    2025-07-09 Brad Bateman - created
#>
$ErrorActionPreference = 'Stop';
#############################################
#<Params>
# Set $RuntimeSymLinksConfigPath to the path under "%localappdata%\Microsoft\Dynamics365\RuntimeSymLinks\{yourConfig}"
# By default, it will use the most recently modified config folder, or you can override the $RuntimeSymLinksConfigPath to a custom value.
$RuntimeSymLinksConfigPath = join-path "$($env:LOCALAPPDATA)" -ChildPath "Microsoft\Dynamics365\RuntimeSymLinks";
$configName = (gci "$RuntimeSymLinksConfigPath" | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1).Name

$RuntimeSymLinksConfigPath = Join-Path $RuntimeSymLinksConfigPath -ChildPath $configName

$debug = $true;
#</Params>
#############################################
$customMetadataSourcePath = Join-Path "$RuntimeSymLinksConfigPath" "ZZZZ__Metadata"
$systemMetadataSourcePath = Join-Path "$RuntimeSymLinksConfigPath" "PackagesLocalDirectory"
$targetRootPath = Join-Path "$RuntimeSymLinksConfigPath" "xxceTraceParserPackagesLocalDirectory"
$removeAOSDirIfExists = $true;

if(-not (Test-Path $RuntimeSymLinksConfigPath))
{
    Write-Error "RuntimeSymLinksConfigPath folder not found: $RuntimeSymLinksConfigPath"
}
elseif($RuntimeSymLinksConfigPath -inotlike '*\Microsoft\Dynamics365\RuntimeSymLinks\*')
{
    Write-Error "RuntimeSymLinksConfigPath doesn not contain expected path with RuntimeSymLinks: $RuntimeSymLinksConfigPath"
}

if(-not (Test-Path $targetRootPath))
{
    New-Item $targetRootPath -ItemType Directory
}

if(-not (Test-Path $customMetadataSourcePath))
{
    Write-Error "Custom metadata folder not found: $customMetadataSourcePath"
}
if(-not (Test-Path $systemMetadataSourcePath))
{
    Write-Error "System metadata folder not found: $systemMetadataSourcePath"
}

$RepoModelFolders = Get-ChildItem $customMetadataSourcePath -Directory
$RepoModelFolders += Get-ChildItem $systemMetadataSourcePath -Directory

foreach ($ModelFolder in $RepoModelFolders)
{
    $Target =  $ModelFolder.FullName
    $newPath = Join-Path "$targetRootPath" "$($ModelFolder.Name)"
    if((Test-Path $newPath) -and $removeAOSDirIfExists)
    {
        Write-Warning "Removing dir $newPath"
        if($debug -eq $false)
        {
            cmd /c rmdir "$newPath" | Out-Null
        }
        else
        {
            Write-Host '  Skipped because debug is enabled' -BackgroundColor Gray
        }

    }

    Write-Host "Create symlink to $Target in $newPath"
    if($debug -eq $false)
    {
        New-Item -ItemType SymbolicLink -Path "$targetRootPath" -Name "$($ModelFolder.Name)" -Value "$Target" | Out-Null
    }
    else
    {
        Write-Host '  Skipped because debug is enabled' -BackgroundColor Gray
    }
}

Write-Host "Completed successfully for path: $targetRootPath" -BackgroundColor Green

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions