- Fixed sf-apex-run.ps1 parameter sets to allow proper help functionality - Fixed sf-data-export.ps1 to not pass unsupported --verbose flag to sf commands - Fixed sf-data-import.ps1 command structure to use correct sf data import bulk/tree commands - Removed --verbose flag from sf data commands as they don't support it - All scripts now properly work with their respective parameter combinations - Comprehensive testing completed with all functionality verified Testing results: ✅ sf-check.ps1 - Working correctly ✅ sf-org-info.ps1 - Working correctly ✅ sf-web-open.ps1 - Working correctly ✅ sf-apex-run.ps1 - Fixed parameter sets, now working ✅ sf-deploy.ps1 - Working correctly ✅ sf-dry-run.ps1 - Working correctly ✅ sf-data-export.ps1 - Fixed --verbose flag issue, now working ✅ sf-data-import.ps1 - Fixed command structure, now working ✅ sf-retrieve.ps1 - Working correctly ✅ sf-test-run.ps1 - Working correctly ✅ sf-logs-tail.ps1 - Working correctly ✅ sf-org-create.ps1 - Working correctly
328 lines
10 KiB
PowerShell
328 lines
10 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 VerboseOutput
|
|
Enable verbose output (alias: -ve)
|
|
|
|
.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")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[Alias("qy")]
|
|
[string]$Query,
|
|
|
|
[Parameter(ParameterSetName="File")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[Alias("fl")]
|
|
[string]$File,
|
|
|
|
[Parameter(ParameterSetName="SObject")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[Alias("so")]
|
|
[string]$SObject,
|
|
|
|
[Parameter(ParameterSetName="Query")]
|
|
[Parameter(ParameterSetName="File")]
|
|
[Parameter(ParameterSetName="SObject")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[Alias("ot")]
|
|
[string]$Output = "export.csv",
|
|
|
|
[Parameter(ParameterSetName="Query")]
|
|
[Parameter(ParameterSetName="File")]
|
|
[Parameter(ParameterSetName="SObject")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[Alias("to")]
|
|
[string]$TargetOrg,
|
|
|
|
[Parameter(ParameterSetName="Query")]
|
|
[Parameter(ParameterSetName="File")]
|
|
[Parameter(ParameterSetName="SObject")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[ValidateSet("csv", "json")]
|
|
[Alias("fm")]
|
|
[string]$Format = "csv",
|
|
|
|
[Parameter(ParameterSetName="Query")]
|
|
[Parameter(ParameterSetName="File")]
|
|
[Parameter(ParameterSetName="SObject")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[Alias("bk")]
|
|
[switch]$Bulk,
|
|
|
|
[Parameter(ParameterSetName="Query")]
|
|
[Parameter(ParameterSetName="File")]
|
|
[Parameter(ParameterSetName="SObject")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[Alias("wt")]
|
|
[int]$Wait = 10,
|
|
|
|
[Parameter(ParameterSetName="Query")]
|
|
[Parameter(ParameterSetName="File")]
|
|
[Parameter(ParameterSetName="SObject")]
|
|
[Parameter(ParameterSetName="Help")]
|
|
[Alias("ve")]
|
|
[switch]$VerboseOutput,
|
|
|
|
[Parameter(ParameterSetName="Help", Mandatory=$true)]
|
|
[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
|
|
|
|
# Note: sf data commands don't support --verbose flag
|
|
# VerboseOutput only affects the script's own output (query preview)
|
|
|
|
# Display export information
|
|
Write-Host ""
|
|
Write-Host "📊 Starting Data Export" -ForegroundColor Blue
|
|
Write-Host "=======================" -ForegroundColor Blue
|
|
|
|
# Show query preview if verbose
|
|
if ($VerboseOutput) {
|
|
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 ($VerboseOutput) {
|
|
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
|
|
}
|