DataverseTableManager.CLI
1.4.8
dotnet tool install --global DataverseTableManager.CLI --version 1.4.8
dotnet new tool-manifest
dotnet tool install --local DataverseTableManager.CLI --version 1.4.8
#tool dotnet:?package=DataverseTableManager.CLI&version=1.4.8
nuke :add-package DataverseTableManager.CLI --version 1.4.8
Dataverse Table Manager (DTM)
A powerful CLI tool for managing Dataverse tables, columns, forms, and webresources from JSON schema definitions. Build, deploy, and manage your Dataverse data model with ease.
🚀 Features
Table & Column Management
- ✅ Create, update, and delete Dataverse tables and columns from JSON
- ✅ Support for all column types (Text, Number, Choice, Lookup, Boolean, etc.)
- ✅ Global and local option sets (choice columns)
- ✅ Relationship management with cascade configurations
- ✅ Publisher prefix auto-generation
- ✅ Dry-run mode to preview changes
- ✅ Solution integration with automatic component binding
WebResource Management
- ✅ Upload/download webresources (HTML, CSS, JS, XML, images)
- ✅ File watching with auto-sync
- ✅ Pattern-based include/exclude filtering
- ✅ Solution integration and auto-publish
- ✅ Bulk operations with progress reporting
Form Management
- ✅ Create complete Main form layouts with tabs, sections, and fields
- ✅ Export existing Main forms to JSON for backup or migration
- ✅ Validate form definitions against table metadata
- ✅ Rich JSON schema for form layout definition
- ✅ Control visibility of tabs, sections, and fields
- ✅ Support for Main forms (other form types not currently supported)
Developer Experience
- ✅ Rich CLI with colored output and progress bars
- ✅ Profile-based authentication management
- ✅ JSON schema validation with helpful error messages
- ✅ Comprehensive help system
- ✅ Cross-platform support (Windows, Linux, macOS)
📦 Installation
Global CLI Tool (Recommended)
# Install from NuGet
dotnet tool install --global DataverseTableManager.CLI
# Verify installation
dtm --version
Download Executable
Download the latest release from GitHub Releases
⚡ Quick Start
1. Authentication Setup
# Create authentication profile
dtm auth create --name "Dev" --environment "https://yourorg.crm.dynamics.com"
# Set as active profile
dtm auth set --name "Dev"
# List all profiles
dtm auth list
2. Create Your First Table
Create a schema.json file:
{
"tables": [
{
"logicalName": "cjs_tutoringsession",
"displayName": "Tutoring Session",
"description": "Tracks tutoring sessions",
"ownership": "UserOwned",
"settings": {
"enableActivities": true,
"enableNotes": true,
"isAuditEnabled": true
},
"primaryName": {
"displayName": "Session Name",
"maxLength": 200
},
"columns": [
{
"logicalName": "cjs_duration",
"type": "Integer",
"displayName": "Duration (mins)",
"min": 0,
"max": 1440,
"requiredLevel": "ApplicationRequired"
},
{
"logicalName": "cjs_sessiondate",
"type": "DateTime",
"displayName": "Session Date",
"format": "DateOnly",
"requiredLevel": "ApplicationRequired"
},
{
"logicalName": "cjs_level",
"type": "Choice",
"displayName": "Level",
"choice": {
"globalName": "cjs_level_global"
}
},
{
"logicalName": "cjs_topics",
"type": "MultiSelect",
"displayName": "Topics",
"choice": {
"localOptions": ["Math", "Science", "English", "History"]
}
},
{
"logicalName": "cjs_studentid",
"type": "Lookup",
"displayName": "Student",
"targets": ["contact"],
"relationship": {
"schemaName": "cjs_TutoringSession_Contact",
"cascade": "Assign,Share,Unshare,Reparent,RemoveLink"
}
}
]
}
]
}
3. Deploy to Dataverse
# Dry run to preview changes
dtm upsert schema.json --solution "YourSolution" --dry-run
# Deploy for real
dtm upsert schema.json --solution "YourSolution"
📖 Usage Guide
Table Management Commands
# Create/update tables from JSON
dtm upsert <file> --solution <solution> [--dry-run] [--verbose]
# Delete tables
dtm delete <file> --solution <solution> [--dry-run] [--force]
# Generate schema template
dtm schema generate --output schema.json [--table-count 3]
# Validate JSON schema
dtm schema validate <file>
WebResource Management Commands
# Upload webresources
dtm webresource push --path ./webresources --solution MySolution --publish
# Download webresources
dtm webresource pull --path ./webresources --solution MySolution --overwrite
# List webresources
dtm webresource list --solution MySolution --type JS --verbose
# Watch for changes (auto-sync)
dtm webresource watch --path ./webresources --solution MySolution --publish
# Delete webresources
dtm webresource delete --names "js/main.js,css/styles.css" --force
Forms Management Commands
# Create a new Main form with schema
dtm forms create --table contact --name "Enhanced Contact Form" --schema ./contact-form.json --solution MySolution
# Create a basic Main form
dtm forms create --table account --name "Simple Account Form" --type Main --solution MySolution
# Export existing Main form to JSON
dtm forms export --table contact --form "Information" --output ./contact-form.json
# Validate form definition
dtm forms validate --file ./contact-form.json
# Create form with dry-run (preview only)
dtm forms create --table lead --name "Lead Form" --schema ./lead-form.json --dry-run --verbose
Authentication Management
# Create profile
dtm auth create --name <name> --environment <url>
# List profiles
dtm auth list
# Set active profile
dtm auth set --name <name>
# Delete profile
dtm auth delete --name <name>
🏗️ JSON Schema Reference
Table Definition
{
"logicalName": "prefix_tablename", // Required: Table logical name
"displayName": "Table Display Name", // Required: Friendly name
"description": "Table description", // Optional: Description
"pluralDisplayName": "Tables", // Optional: Plural form
"ownership": "UserOwned", // UserOwned | OrganizationOwned
"tableType": "Standard", // Standard | Activity | Virtual
"settings": {
"enableActivities": true, // Enable activities
"enableNotes": true, // Enable notes/attachments
"enableConnections": false, // Enable connections
"isAuditEnabled": true, // Enable auditing
"isDuplicateDetectionEnabled": false,// Enable duplicate detection
"isBusinessProcessEnabled": false // Enable business process flows
},
"primaryName": {
"displayName": "Name", // Primary name field display name
"maxLength": 100 // Max length (default: 100)
},
"delete": false // Set to true to delete table
}
Column Types
Text Column
{
"logicalName": "prefix_textfield",
"type": "Text",
"displayName": "Text Field",
"description": "A text field",
"maxLength": 100,
"requiredLevel": "None" // None | Recommended | ApplicationRequired
}
Number Columns
{
"logicalName": "prefix_number",
"type": "Integer", // Integer | Decimal | Money
"displayName": "Number Field",
"min": 0,
"max": 1000,
"precision": 2 // For Decimal/Money types
}
Choice Column (Local Options)
{
"logicalName": "prefix_status",
"type": "Choice",
"displayName": "Status",
"choice": {
"localOptions": ["Active", "Inactive", "Pending"]
}
}
Choice Column (Global Option Set)
{
"logicalName": "prefix_priority",
"type": "Choice",
"displayName": "Priority",
"choice": {
"globalName": "priority_global"
}
}
Lookup Column
{
"logicalName": "prefix_customerid",
"type": "Lookup",
"displayName": "Customer",
"targets": ["account", "contact"],
"relationship": {
"schemaName": "prefix_table_customer",
"cascade": "Assign,Share,Unshare,Reparent,RemoveLink"
}
}
Boolean Column
{
"logicalName": "prefix_isactive",
"type": "Boolean",
"displayName": "Is Active",
"trueLabel": "Yes",
"falseLabel": "No"
}
DateTime Column
{
"logicalName": "prefix_duedate",
"type": "DateTime",
"displayName": "Due Date",
"format": "DateOnly" // DateOnly | DateAndTime
}
Cascade Options
Available cascade behaviors for relationships:
Assign- Cascade on assignShare- Cascade on shareUnshare- Cascade on unshareReparent- Cascade on reparentDelete- Cascade on deleteMerge- Cascade on mergeRemoveLink- Remove link only
Combine multiple behaviors with commas: "Assign,Share,Unshare,Reparent,RemoveLink"
🔧 Advanced Usage
Publisher Prefix Auto-Generation
DTM automatically generates logical names using your solution's publisher prefix:
# If your solution has publisher prefix "cjs", this JSON:
{
"logicalName": "tutoringsession",
"displayName": "Tutoring Session"
}
# Becomes: "cjs_tutoringsession" in Dataverse
Batch Operations
# Process multiple schema files
dtm upsert schema1.json schema2.json --solution MySolution
# Use wildcards
dtm upsert schemas/*.json --solution MySolution
WebResource File Patterns
# Include only JavaScript files
dtm wr push --include "**/*.js"
# Exclude node_modules and build artifacts
dtm wr push --exclude "node_modules/**,dist/**,*.min.*"
# Complex patterns
dtm wr push --include "src/**" --exclude "src/**/*.test.js"
Environment-Specific Workflows
# Development
dtm auth create --name "Dev" --environment "https://yourorg-dev.crm.dynamics.com"
dtm upsert schema.json --profile "Dev" --solution "DevSolution"
# Production
dtm auth create --name "Prod" --environment "https://yourorg.crm.dynamics.com"
dtm upsert schema.json --profile "Prod" --solution "ProdSolution"
🎯 Best Practices
1. Schema Organization
- Keep table definitions in separate files for large projects
- Use consistent naming conventions
- Document your schema with descriptions
- Version control your JSON schemas
2. Solution Management
- Always specify a solution to avoid components in the default solution
- Use meaningful solution names and descriptions
- Separate development and production solutions
3. Testing Strategy
- Always use
--dry-runbefore actual deployment - Test in development environment first
- Validate your JSON schema before deployment
- Use version control to track changes
4. WebResource Organization
webresources/
├── css/
│ ├── global.css
│ └── forms.css
├── js/
│ ├── common.js
│ ├── account.form.js
│ └── contact.form.js
├── html/
│ └── help.html
└── images/
├── logo.png
└── icons/
🚨 Troubleshooting
Common Issues
Authentication Errors
# Check active profile
dtm auth list
# Recreate profile if needed
dtm auth delete --name "ProfileName"
dtm auth create --name "ProfileName" --environment "URL"
Schema Validation Errors
# Validate schema first
dtm schema validate schema.json
# Check for common issues:
# - Missing required fields
# - Invalid column types
# - Malformed JSON
Connection Issues
- Verify environment URL is correct
- Check network connectivity
- Ensure user has appropriate permissions
- Try recreating the authentication profile
Permission Issues
Required Dataverse permissions:
- System Customizer role or equivalent
- Create, Read, Write permissions on:
- Entity (Table) metadata
- Attribute (Column) metadata
- Solution components
- WebResource entities (for webresource commands)
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone repository
git clone https://github.com/wezthecode/dataverse-table-manager.git
cd DataverseTableManager
# Build
dotnet build
# Run tests
dotnet test
# Run CLI locally
dotnet run --project DataverseTableManager.CLI -- --help
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
This project was inspired by and builds upon patterns from:
Greg.Xrm.Command by Gered King - A fantastic CLI tool for Dataverse operations that provided excellent patterns for command structure, authentication management, and professional CLI UX. Many of our CLI design decisions and authentication patterns were influenced by this outstanding project.
Javista.AttributesFactory - A tool for bulk attribute creation that demonstrated clean approaches to Dataverse metadata operations.
Special thanks to the Microsoft Dataverse team for providing the foundational tools and APIs that make this project possible.
📞 Support
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 📧 Email: your.email@example.com
Made with ❤️ for the Dataverse community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.4.8 | 226 | 10/6/2025 |
Enhanced authentication with token caching, improved error handling, and comprehensive form management capabilities.