How to Export BizTalk Applications assemblies (resources) from the XML to a local folders with PowerShell (Part 2)

  • Sandro Pereira
  • Nov 20, 2025
  • 4 min read

Following the nightmare exportation story in the previous blog post, I decided to create the final solution that combines a bit of the logic from the last script with a simplified XML and some manual work, with the help of ChatGPT.

📝 One-Minute Brief

This is a PowerShell script that goes to an XML File with a list of all assemblies of a specific BizTalk application and copies the DLL from the GAC to a local folder per application.

The logic was:

  • I manually copied the resource list from the BizTalk Server Administration Console by selecting all the lines and CTRL-C
  • And past it (CTRL-V) to different sheets inside an Excel file – each sheet is an application, and each sheet contains the list of resources for that application. Optionally, you can delete the unnecessary columns
  • Then I ask ChatGPT to convert this Excel in a simple XML file with this format:
<?xml version='1.0' encoding='utf-8'?>
<Applications>
  <Application name="Target">
    <Assembly>Target.Common.Messaging</Assembly>
    <Assembly>Target.Common.Processing</Assembly>
    <Assembly>Target.TargetPublishNURCT.Messaging</Assembly>
    <Assembly>Target.TargetPublishNURCT.Staging</Assembly>
    <Assembly>Target.TargetPublishODS.Messaging</Assembly>
    <Assembly>Target.TargetPublishODS.Processing</Assembly>
    <Assembly>Target.TargetPublishODS.Staging</Assembly>
    <Assembly>Target.TargetReceiveInfoware.messaging</Assembly>
    <Assembly>Target.TargetReceiveInfoware.Processing</Assembly>
    <Assembly>Target.TargetReceiveInfoware.Staging</Assembly>
    <Assembly>Name</Assembly>
  </Application>
  <Application name="Sales">
    <Assembly>...</Assembly>
    <Assembly>Name</Assembly>
  </Application>
  ...
</Applications>

This is a simple, clean XML file containing a list of all assemblies for each application. Now, the last step was to create a PowerShell script that goes to that XML and:

  • Per application, creates a local folder
  • And copies from the Global Assembly Cache (GAC) the list of assemblies (DLL) to that local folder

Here is a sample of the script:

# Iterate Applications
$apps = $xml.SelectNodes('/Applications/Application')
if (-not $apps -or $apps.Count -eq 0) {
    throw "No <Application> nodes found in XML: $XmlPath"
}

foreach ($app in $apps) {
    $appName = [string]$app.GetAttribute('name')
    if ([string]::IsNullOrWhiteSpace($appName)) { continue }

    # Sanitize folder name (Windows forbids these chars)
    $safeApp = ($appName -replace '[\\/:*?"<>|]', '_').Trim()
    $appFolder = Join-Path $ExportRoot $safeApp

    if (-not (Test-Path -LiteralPath $appFolder)) {
        New-Item -ItemType Directory -Path $appFolder | Out-Null
    }

    Write-Host "`n== Application: $appName ==" -ForegroundColor Cyan

    # Assemblies for this application
    $asmNodes = $app.SelectNodes('./Assembly')
    if (-not $asmNodes -or $asmNodes.Count -eq 0) {
        Write-Warning "No <Assembly> items for application '$appName'."
        continue
    }

    foreach ($node in $asmNodes) {
        $asmName = [string]$node.InnerText
        if ([string]::IsNullOrWhiteSpace($asmName)) { continue }

        $dllPath = $null
        $hitsAll = @()

        foreach ($bucket in $gacBuckets) {
            $nameDir = Join-Path (Join-Path $gacRoot $bucket) $asmName
            if (-not (Test-Path -LiteralPath $nameDir)) { continue }

            # Gather any <asmName>.dll under version folders
            $hits = @(Get-ChildItem -LiteralPath $nameDir -Recurse -Filter ("{0}.dll" -f $asmName) -ErrorAction SilentlyContinue)
            if ($hits.Count -gt 0) {
                $hitsAll += $hits
            }
        }

        if ($hitsAll.Count -eq 0) {
            Write-Warning "GAC dll not found for '$asmName'."
            $summary += [pscustomobject]@{ Application=$appName; Assembly=$asmName; Source=''; Dest=''; Result='NotFound' }
            continue
        }

        # Prefer highest version by parsing parent folder name "<version>__<pkt>"
        $best = $hitsAll |
            Sort-Object -Descending -Property @{
                Expression = {
                    # Try to extract version from parent dir name
                    $parent = Split-Path $_.DirectoryName -Leaf
                    $ver = $null
                    if ($parent -match $verFolderPattern) {
                        try { [version]$matches['ver'] } catch { [version]'0.0.0.0' }
                    } else { [version]'0.0.0.0' }
                }
            } |
            Select-Object -First 1

        $dllPath = $best.FullName

        try {
            $dest = Join-Path $appFolder ("{0}.dll" -f $asmName)
            Copy-Item -LiteralPath $dllPath -Destination $dest -Force:$Overwrite
            Write-Host ("Copied: {0}  ->  {1}" -f $asmName, $dest) -ForegroundColor Green
            $summary += [pscustomobject]@{ Application=$appName; Assembly=$asmName; Source=$dllPath; Dest=$dest; Result='Copied' }
        }
        catch {
            Write-Warning ("Failed to copy {0}: {1}" -f $asmName, $_.Exception.Message)
            $summary += [pscustomobject]@{ Application=$appName; Assembly=$asmName; Source=$dllPath; Dest=''; Result="Error: $($_.Exception.Message)" }
        }
    }
}

This was able to solve all my problems. Unfortunately, I had to perform some manual tasks, but in a few minutes, I had all the necessary DLLs (assemblies) to import and install in another environment – we will see that in another blog post.

Download

THIS POWERSHELL SCRIPT IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

You can download the PowerShell Script used from GitHub here:

Hope you find this helpful! If you enjoyed the content or found it useful, and wish to support our efforts to create more, you can contribute to purchasing a Star Wars Lego set for my son!

Author: Sandro Pereira

Sandro Pereira lives in Portugal and works as a consultant at DevScope. In the past years, he has been working on implementing Integration scenarios both on-premises and cloud for various clients, each with different scenarios from a technical point of view, size, and criticality, using Microsoft Azure, Microsoft BizTalk Server and different technologies like AS2, EDI, RosettaNet, SAP, TIBCO etc. He is a regular blogger, international speaker, and technical reviewer of several BizTalk books all focused on Integration. He is also the author of the book “BizTalk Mapping Patterns & Best Practices”. He has been awarded MVP since 2011 for his contributions to the integration community.

Leave a Reply

Your email address will not be published. Required fields are marked *

The Ultimate Cloud
Management Platform for Azure

Supercharge your Azure Cost Saving

Learn More
Turbo360 Widget

Back to Top