Files
sf-cli-wrapper/sf-data-export.ps1
reynold 4bae7d48fa Update data export/import scripts to use latest Salesforce CLI commands
- Updated sf-data-export to use 'sf data export bulk' instead of deprecated 'sf data export'
- Updated sf-data-export.ps1 to use 'sf data export bulk' command structure
- Updated sf-data-import to use 'sf data import bulk' for better compatibility
- All scripts now comply with the latest Salesforce CLI command structure
- Fixes compatibility issues with newer SF CLI versions
2025-08-28 18:22:43 +08:00

302 lines
8.8 KiB
PowerShell

#!/usr/bin/env pwsh
<#
.SYNOPSIS
Data export wrapper for Salesforce CLI with SOQL query support
.DESCRIPTION
A user-friendly wrapper around 'sf data export' that simplifies data export
from Salesforce orgs with SOQL query support, multiple formats, and intelligent defaults.
.PARAMETER Query
SOQL query to export data (alias: -qy)
.PARAMETER File
File containing SOQL query (alias: -fl)
.PARAMETER SObject
Standard object query (exports common fields) (alias: -so)
.PARAMETER Output
Output file path (default: export.csv) (alias: -ot)
.PARAMETER TargetOrg
Target org username or alias (alias: -to)
.PARAMETER Format
Output format: csv, json (default: csv) (alias: -fm)
.PARAMETER Bulk
Use bulk API for large datasets (alias: -bk)
.PARAMETER Wait
Wait time in minutes (default: 10) (alias: -wt)
.PARAMETER Verbose
Enable verbose output (alias: -vb)
.PARAMETER Help
Show this help message (alias: -hp)
.EXAMPLE
.\sf-data-export.ps1 -qy "SELECT Id, Name FROM Account LIMIT 100"
.\sf-data-export.ps1 -so Account -fm json -ot accounts.json
.\sf-data-export.ps1 -fl queries/contacts.soql -bk -wt 15
.\sf-data-export.ps1 -qy "SELECT Id FROM User" -to production
.NOTES
This script automatically checks for Salesforce CLI installation and runs
diagnostics if the CLI is not found.
#>
param(
[Parameter(ParameterSetName="Query")]
[Alias("qy")]
[string]$Query,
[Parameter(ParameterSetName="File")]
[Alias("fl")]
[string]$File,
[Parameter(ParameterSetName="SObject")]
[Alias("so")]
[string]$SObject,
[Alias("ot")]
[string]$Output = "export.csv",
[Alias("to")]
[string]$TargetOrg,
[ValidateSet("csv", "json")]
[Alias("fm")]
[string]$Format = "csv",
[Alias("bk")]
[switch]$Bulk,
[Alias("wt")]
[int]$Wait = 10,
[Alias("vb")]
[switch]$Verbose,
[Alias("hp")]
[switch]$Help
)
# Show help if requested
if ($Help) {
Get-Help $MyInvocation.MyCommand.Path -Detailed
exit 0
}
# Function to check if Salesforce CLI is installed
function Test-SalesforceCLI {
try {
$null = Get-Command sf -ErrorAction Stop
return $true
} catch {
return $false
}
}
# Function to run sf-check diagnostics
function Invoke-SalesforceCheck {
$checkScript = if (Test-Path "sf-check.ps1") {
".\sf-check.ps1"
} elseif (Test-Path "sf-check.sh") {
"bash sf-check.sh"
} else {
$null
}
if ($checkScript) {
Write-Host "Running Salesforce CLI diagnostics..." -ForegroundColor Yellow
Invoke-Expression $checkScript
} else {
Write-Host "Salesforce CLI not found and no diagnostic script available." -ForegroundColor Red
Write-Host "Please install the Salesforce CLI: https://developer.salesforce.com/tools/salesforcecli" -ForegroundColor Red
}
}
# Function to build standard object query
function New-SObjectQuery {
param([string]$SObjectType)
switch ($SObjectType) {
"Account" {
return "SELECT Id, Name, Type, Industry, Phone, Website, BillingCity, BillingState, BillingCountry FROM Account"
}
"Contact" {
return "SELECT Id, FirstName, LastName, Email, Phone, AccountId, Account.Name FROM Contact"
}
"Lead" {
return "SELECT Id, FirstName, LastName, Email, Phone, Company, Status, Source FROM Lead"
}
"Opportunity" {
return "SELECT Id, Name, AccountId, Account.Name, Amount, CloseDate, StageName, Probability FROM Opportunity"
}
"Case" {
return "SELECT Id, CaseNumber, Subject, Status, Priority, Origin, AccountId, Account.Name, ContactId, Contact.Name FROM Case"
}
"User" {
return "SELECT Id, Name, Email, Username, Profile.Name, IsActive, LastLoginDate FROM User"
}
default {
return "SELECT Id, Name FROM $SObjectType"
}
}
}
# Function to validate SOQL query
function Test-SOQLQuery {
param([string]$QueryText)
if ($QueryText -notmatch '^\s*SELECT\s+') {
Write-Host "Error: Query must start with SELECT" -ForegroundColor Red
return $false
}
return $true
}
# Silently check for Salesforce CLI
if (-not (Test-SalesforceCLI)) {
Invoke-SalesforceCheck
exit 1
}
# Validate that exactly one query method is specified
$queryMethods = @($Query, $File, $SObject | Where-Object { $_ }).Count
if ($queryMethods -eq 0) {
Write-Host "Error: Must specify one of: -Query, -File, or -SObject" -ForegroundColor Red
Write-Host ""
Write-Host "Usage examples:" -ForegroundColor Yellow
Write-Host " .\sf-data-export.ps1 -Query `"SELECT Id, Name FROM Account`"" -ForegroundColor Gray
Write-Host " .\sf-data-export.ps1 -File queries/accounts.soql" -ForegroundColor Gray
Write-Host " .\sf-data-export.ps1 -SObject Account" -ForegroundColor Gray
Write-Host ""
Write-Host "Use -Help for detailed usage information." -ForegroundColor Yellow
exit 1
}
if ($queryMethods -gt 1) {
Write-Host "Error: Can only specify one of: -Query, -File, or -SObject" -ForegroundColor Red
exit 1
}
# Determine the final query
$finalQuery = ""
if ($Query) {
$finalQuery = $Query
Write-Host "Using inline query" -ForegroundColor Green
} elseif ($File) {
if (-not (Test-Path $File)) {
Write-Host "Error: Query file not found: $File" -ForegroundColor Red
exit 1
}
$finalQuery = Get-Content $File -Raw
Write-Host "Using query from file: $File" -ForegroundColor Green
} elseif ($SObject) {
$finalQuery = New-SObjectQuery $SObject
Write-Host "Using standard query for $SObject" -ForegroundColor Green
}
# Validate the query
if (-not (Test-SOQLQuery $finalQuery)) {
exit 1
}
# Build the sf command based on bulk vs regular query
if ($Bulk) {
# Use Bulk API 2.0 for large datasets
$sfArgs = @("data", "export", "bulk", "--query", $finalQuery, "--output-file", $Output, "--result-format", $Format)
if ($Wait -ne 10) {
$sfArgs += "--wait"
$sfArgs += $Wait.ToString()
}
Write-Host "Using Bulk API 2.0" -ForegroundColor Yellow
} else {
# Use regular data query for smaller datasets
$sfArgs = @("data", "query", "--query", $finalQuery, "--output-file", $Output, "--result-format", $Format)
}
# Add optional parameters
if ($TargetOrg) {
$sfArgs += "--target-org"
$sfArgs += $TargetOrg
Write-Host "Target org: $TargetOrg" -ForegroundColor Cyan
}
Write-Host "Output format: $Format" -ForegroundColor Cyan
Write-Host "Output file: $Output" -ForegroundColor Cyan
# Add verbose flag if requested
if ($Verbose) {
$sfArgs += "--verbose"
}
# Display export information
Write-Host ""
Write-Host "📊 Starting Data Export" -ForegroundColor Blue
Write-Host "=======================" -ForegroundColor Blue
# Show query preview if verbose
if ($Verbose) {
Write-Host ""
Write-Host "📝 SOQL Query:" -ForegroundColor Yellow
Write-Host "----------------------------------------" -ForegroundColor Gray
Write-Host $finalQuery -ForegroundColor Gray
Write-Host "----------------------------------------" -ForegroundColor Gray
}
# Display the command being run
Write-Host ""
Write-Host "Executing: sf $($sfArgs -join ' ')" -ForegroundColor Gray
Write-Host ""
# Execute the command
try {
& sf @sfArgs
$exitCode = $LASTEXITCODE
Write-Host ""
if ($exitCode -eq 0) {
Write-Host "✅ Data export completed successfully!" -ForegroundColor Green
# Show file information if it exists
if (Test-Path $Output) {
$fileInfo = Get-Item $Output
$fileSize = if ($fileInfo.Length -gt 1MB) {
"{0:N1} MB" -f ($fileInfo.Length / 1MB)
} elseif ($fileInfo.Length -gt 1KB) {
"{0:N1} KB" -f ($fileInfo.Length / 1KB)
} else {
"$($fileInfo.Length) bytes"
}
if ($Format -eq "csv") {
# Count records (excluding header)
$recordCount = (Get-Content $Output).Count - 1
Write-Host "📁 Exported $recordCount records to $Output ($fileSize)" -ForegroundColor Cyan
} else {
Write-Host "📁 Data exported to $Output ($fileSize)" -ForegroundColor Cyan
}
}
if ($Verbose) {
Write-Host "💡 Use a spreadsheet application or text editor to view the exported data" -ForegroundColor Yellow
}
} else {
Write-Host "❌ Data export failed with exit code: $exitCode" -ForegroundColor Red
Write-Host "💡 Check query syntax and permissions" -ForegroundColor Yellow
exit $exitCode
}
} catch {
Write-Host "Error executing sf command: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}