Skip to content

CID Software Solutions LTD

Home » Useful PowerShell Script for Downloading Files from UCM Based on a CSV File

Useful PowerShell Script for Downloading Files from UCM Based on a CSV File

Sometimes we need to download multiple files from Oracle WebCenter Content (UCM) in bulk — for example, after running a BICC extract job, retrieving reports, attachments, or exported data. Manually downloading each file through the UI is time-consuming and error-prone.

Business Challenge

In Oracle Fusion Cloud environments, UCM stores a large number of documents (BICC extracts, BI Publisher reports, custom attachments, etc.). When dealing with hundreds or thousands of files identified via metadata query, there is no simple native bulk-download option in the UI. Developers and functional consultants often need an automated, repeatable way to retrieve these files based on specific criteria (e.g., title pattern or job name).

Our Solution

The PowerShell script below uses the UCM SOAP GET_FILE service to download files listed in a CSV file. The CSV can be easily generated from UCM using a simple query like:

SQL
select DID, DDOCNAME, DDOCTITLE, DDOCAUTHOR 
from revisions 
where DDOCTITLE like '%your pattern or BICC job%'

The script:

  1. Prioritizes meaningful filename from DDOCTITLE (preferred), then DDOCNAME, then fallback to dID.bin
  2. Handles Basic Authentication via the Fusion / UCM endpoint
  3. Parses multipart SOAP response to extract the binary content
  4. Saves files directly in the same folder as the .ps1 script
  5. Includes error handling and logging for each file

Prerequisites

  • PowerShell access
  • Network access to your Fusion UCM SOAP endpoint
  • Valid Fusion / UCM username and password with read permissions on the documents
  • CSV file exported from UCM with columns: DID, DDOCNAME, DDOCTITLE, DDOCAUTHOR

The Script

PowerShell
<#
.SYNOPSIS
    Downloads documents from Oracle Fusion / WebCenter Content (UCM) using SOAP GET_FILE service.
    CSV columns expected: DID, DDDOCNAME, DDOCTITLE, DDOCAUTHOR
    Filename priority:
    1. DDOCTITLE (preferred - usually the meaningful title)
    2. DDDOCNAME
    3. dID.bin (fallback)
    Files are saved in the same folder as this .ps1 script.
.PARAMETER csvFile Path to your CSV file
.PARAMETER fusionUrl Base URL of Fusion environment[](https://yourpod-fa-ext.oraclecloud.com/)
.PARAMETER username Fusion / UCM username
.PARAMETER password Password
#>

param (
    [Parameter(Mandatory=$true)]
    [string]$csvFile,
    [Parameter(Mandatory=$true)]
    [string]$fusionUrl,
    [Parameter(Mandatory=$true)]
    [string]$username,
    [Parameter(Mandatory=$true)]
    [string]$password
)

# Force current directory to be the folder where this script is located
# This ensures files are saved next to the .ps1 file (most predictable)
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
Set-Location -Path $scriptDir -ErrorAction Stop
Write-Output "Saving files to: $scriptDir"

# Normalize Fusion URL
if (-not $fusionUrl.EndsWith('/')) {
    $fusionUrl += '/'
}
$soapEndpoint = $fusionUrl + "idcws/GenericSoapPort"

# Load CSV
try {
    $documents = Import-Csv -Path $csvFile -ErrorAction Stop
} catch {
    Write-Error "Cannot read CSV file: $($_.Exception.Message)"
    exit 1
}

# Basic Authentication
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$username:$password"))
$authHeader = "Basic $base64AuthInfo"

foreach ($doc in $documents) {
    $did = $doc.DID
    if ([string]::IsNullOrWhiteSpace($did)) {
        Write-Warning "Skipping row - missing DID"
        continue
    }

    # Get name sources safely (compatible with PowerShell 5.1)
    $title   = if ($doc.DDOCTITLE) { $doc.DDOCTITLE.Trim() } else { "" }
    $docname = if ($doc.DDDOCNAME) { $doc.DDDOCNAME.Trim() } else { "" }

    Write-Output "Processing dID: $did"
    Write-Output " Title (DDOCTITLE) : '$title'"
    Write-Output " DocName (DDDOCNAME): '$docname'"

    # -------------------------------------------------------------------------
    # SOAP Request
    # -------------------------------------------------------------------------
    $soapBody = @"
                <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ucm="http://www.oracle.com/UCM">
                   <soapenv:Header/>
                   <soapenv:Body>
                      <ucm:GenericRequest webKey="cs">
                         <ucm:Service IdcService="GET_FILE">
                            <ucm:Document>
                               <ucm:Field name="dID">$did</ucm:Field>
                            </ucm:Document>
                         </ucm:Service>
                      </ucm:GenericRequest>
                   </soapenv:Body>
                </soapenv:Envelope>
                "@
                
    $headers = @{
        "Authorization" = $authHeader
        "Content-Type"   = "text/xml;charset=UTF-8"
    }

    try {
        $response = Invoke-WebRequest -Uri $soapEndpoint `
                                      -Method Post `
                                      -Headers $headers `
                                      -Body $soapBody `
                                      -ErrorAction Stop

        if ($response.StatusCode -ne 200) {
            throw "HTTP $($response.StatusCode) $($response.StatusDescription)"
        }

        $rawBytes = $response.Content

        # Extract multipart boundary
        $contentType = $response.Headers["Content-Type"]
        if ($contentType -notmatch 'boundary="?([^";]+)"?') {
            throw "No multipart boundary found in Content-Type"
        }
        $boundary = "--" + $matches[1]

        $encoding = [Text.Encoding]::GetEncoding('iso-8859-1')
        $rawString = $encoding.GetString($rawBytes)
        $parts = $rawString -split ([regex]::Escape($boundary))

        if ($parts.Count -lt 3) {
            throw "Unexpected MIME parts count: $($parts.Count)"
        }

        $filePart = $parts[2].Trim()
        $headerEndIndex = $filePart.IndexOf("`r`n`r`n")
        if ($headerEndIndex -eq -1) {
            throw "Cannot find end of MIME headers in file part"
        }

        $partHeaders = $filePart.Substring(0, $headerEndIndex)
        $binaryStart = $headerEndIndex + 4
        $binaryString = $filePart.Substring($binaryStart)
        $fileBytes = $encoding.GetBytes($binaryString)

        # Try to get filename from response headers (sometimes present)
        $responseFileName = $null
        if ($partHeaders -match '(?i)filename="?([^";\r\n]+)"?') {
            $responseFileName = $matches[1].Trim()
            Write-Output " Response provided filename: '$responseFileName'"
        }

        # Final filename decision
        $finalFileName = if ($responseFileName) {
            $responseFileName
        } elseif ($title) {
            $title
        } elseif ($docname) {
            $docname
        } else {
            "$did"
        }

        # Clean filename and ensure extension
        $finalFileName = $finalFileName -replace '[<>:"/\\|?*]', '_'
        if (-not $finalFileName.Contains('.')) {
            $finalFileName += ".pdf"   # ← Change to .pdf / .docx / .xlsx / .zip / .bin as appropriate
        }

        # Save file
        [IO.File]::WriteAllBytes($finalFileName, $fileBytes)
        Write-Output "Successfully saved: $finalFileName (size: $($fileBytes.Length) bytes)"
    }
    catch {
        Write-Error "Failed for dID $did$($_.Exception.Message)"
    }
}

Write-Output "All downloads completed."
Write-Output "Files are saved in: $scriptDir"
  1. Export your list of documents from UCM into CSV (use the SQL query shown earlier)
  2. Save the script as Download-UCM-Files.ps1
  3. Open PowerShell and navigate to the script folder
  4. Run:
PowerShell
.\Download-UCM-Files.ps1 -csvFile "C:\temp\my-documents.csv" `
                         -fusionUrl "https://yourpod-fa-ext.oraclecloud.com/" `
                         -username "[email protected]" `
                         -password "YourPassword123"

Files will be saved automatically in the same directory as the script. Adjust the default extension (.pdf) in the script if your files are mostly in another format.

Conclusion

This simple yet powerful PowerShell script saves significant time when working with bulk UCM content in Oracle Fusion projects — especially BICC extracts, report archives, or mass document migrations. It is lightweight, requires no additional modules, and can be easily scheduled or extended.

Need help customizing it further (e.g. proxy support, multi-threading, or different authentication methods)? Contact CID Software Solutions for Oracle Fusion consulting and development support.

The post Useful PowerShell Script for Downloading Files from UCM Based on a CSV File appeared first on CID Software Solutions LTD.


Leave a Reply

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