Not everything needs a dashboard. Sometimes you just need a quick command-line script that answers a specific question or fixes a specific problem. Here are ten Python CLI scripts that every RevOps team should have in their toolkit, each one solving a real problem in under 50 lines of code.

1. Duplicate Account Detector

Find accounts that might be duplicates based on fuzzy name matching:

# dupes.py - Find potential duplicate accounts
from simple_salesforce import Salesforce
from fuzzywuzzy import fuzz
import os, sys

sf = Salesforce(username=os.environ["SF_USERNAME"],
    password=os.environ["SF_PASSWORD"], security_token=os.environ["SF_TOKEN"])

threshold = int(sys.argv[1]) if len(sys.argv) > 1 else 85
accounts = sf.query_all("SELECT Id, Name FROM Account ORDER BY Name")["records"]

for i, a in enumerate(accounts):
    for b in accounts[i+1:i+10]:  # Compare nearby sorted names
        score = fuzz.token_sort_ratio(a["Name"], b["Name"])
        if score >= threshold:
            print(f"[{score}%] '{a['Name']}' <-> '{b['Name']}'")
python dupes.py 90  # Set similarity threshold to 90%

2. Field Utilization Audit

Find out which custom fields are actually being used:

# field_audit.py - Check field fill rates on any object
import sys

obj_name = sys.argv[1] if len(sys.argv) > 1 else "Lead"
desc = getattr(sf, obj_name).describe()

for field in desc["fields"]:
    if field["custom"]:
        query = f"SELECT COUNT(Id) total FROM {obj_name} WHERE {field['name']} != null"
        count = sf.query(query)["records"][0]["total"]
        pct = (count / total_records * 100) if total_records > 0 else 0
        if pct < 10:
            print(f"  LOW USE: {field['name']} ({pct:.1f}% populated)")
python field_audit.py Opportunity

3. Owner Reassignment Script

Bulk reassign records from one owner to another:

# reassign.py - Reassign records between owners
old_owner, new_owner = sys.argv[1], sys.argv[2]
query = f"SELECT Id FROM Account WHERE OwnerId = '{old_owner}'"
records = sf.query_all(query)["records"]

updates = [{"Id": r["Id"], "OwnerId": new_owner} for r in records]
sf.bulk.Account.update(updates, batch_size=200)
print(f"Reassigned {len(updates)} accounts")

4. Stale Pipeline Report

List opportunities that have not been modified in N days:

# stale_pipeline.py - Find stale opportunities
days = int(sys.argv[1]) if len(sys.argv) > 1 else 60
query = f"""SELECT Name, StageName, Amount, Owner.Name, LastModifiedDate
    FROM Opportunity WHERE IsClosed = false
    AND LastModifiedDate < LAST_N_DAYS:{days} ORDER BY Amount DESC"""

for r in sf.query_all(query)["records"]:
    print(f"${r['Amount']:>12,.0f}  {r['StageName']:<20}  {r['Name']}")

5. Data Export to CSV

Quick export any SOQL query to CSV:

# export.py - Export any SOQL query to CSV
import csv, sys

query = sys.argv[1]
results = sf.query_all(query)["records"]

if results:
    keys = [k for k in results[0].keys() if k != "attributes"]
    writer = csv.DictWriter(sys.stdout, fieldnames=keys, extrasaction="ignore")
    writer.writeheader()
    for r in results:
        writer.writerow(r)
python export.py "SELECT Name, Email FROM Contact LIMIT 1000" > contacts.csv

6. Permission Set Checker

List all users assigned to a specific permission set:

# perms.py - Check permission set assignments
perm_name = sys.argv[1]
query = f"""SELECT Assignee.Name, Assignee.Profile.Name
    FROM PermissionSetAssignment
    WHERE PermissionSet.Name = '{perm_name}'"""

for r in sf.query_all(query)["records"]:
    print(f"{r['Assignee']['Name']:<30} {r['Assignee']['Profile']['Name']}")

7. Missing Field Finder

Identify records that are missing critical fields:

# missing_fields.py - Find records missing required data
required = ["Email", "Phone", "Title", "Company"]
for field in required:
    query = f"SELECT COUNT(Id) total FROM Lead WHERE {field} = null AND IsConverted = false"
    count = sf.query(query)["records"][0]["total"]
    print(f"{field:<20} {count:>6} leads missing")

8. Opportunity Stage Duration

Calculate average time spent in each stage:

# stage_duration.py - Avg days in each opportunity stage
query = """SELECT StageName, AVG(days_in_stage__c) avg_days, COUNT(Id) total
    FROM Opportunity WHERE IsClosed = true AND IsWon = true
    GROUP BY StageName ORDER BY StageName"""

for r in sf.query(query)["records"]:
    print(f"{r['StageName']:<25} {r['avg_days']:>6.1f} days  ({r['total']} deals)")

9. Inactive User Report

Find active licenses assigned to users who have not logged in recently:

# inactive_users.py - Users who haven't logged in for 90+ days
query = """SELECT Name, Profile.Name, LastLoginDate
    FROM User WHERE IsActive = true
    AND LastLoginDate < LAST_N_DAYS:90 ORDER BY LastLoginDate"""

for r in sf.query_all(query)["records"]:
    print(f"{r['Name']:<30} Last login: {r['LastLoginDate'][:10]}")

10. Quick Record Count Dashboard

Get a snapshot of record counts across your key objects:

# counts.py - Record counts for key objects
objects = ["Account", "Contact", "Lead", "Opportunity", "Case"]
for obj in objects:
    count = sf.query(f"SELECT COUNT(Id) total FROM {obj}")["records"][0]["total"]
    print(f"{obj:<15} {count:>10,}")
python counts.py
# Account          12,458
# Contact          45,231
# Lead             23,890
# Opportunity       8,432
# Case             15,678

Key Takeaways

  • A library of small, single-purpose CLI scripts is more practical than one monolithic tool that tries to do everything
  • Each script in this toolkit solves a specific problem in under 50 lines, making them easy to understand, modify, and maintain
  • CLI scripts integrate naturally into cron jobs, CI/CD pipelines, and other automation workflows
  • Start with the two or three scripts that address your biggest pain points and grow the toolkit over time