This skill should be used when the user asks to "add sample data", "populate tables", "seed data", "add test records", "generate sample records", "insert demo data", "fill tables with data", "create test data", or wants to populate their Dataverse tables with sample records so they can test and demo their Power Pages site.
Install with Tessl CLI
npx tessl i github:microsoft/power-platform-skills --skill add-sample-data88
Quality
87%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Populate Dataverse tables with sample records via OData API so users can test and demo their Power Pages sites.
Initial request: $ARGUMENTS
Goal: Confirm PAC CLI auth, acquire an Azure CLI token, and verify API access
Actions:
${CLAUDE_PLUGIN_ROOT}/references/dataverse-prerequisites.md to verify PAC CLI auth, acquire an Azure CLI token, and confirm API access. Store the environment URL as $envUrl.Output: Authenticated session with valid token and confirmed API access
Goal: Find the custom tables available in the user's Dataverse environment
Actions:
.datamodel-manifest.json (Preferred)Check if .datamodel-manifest.json exists in the project root (written by the setup-datamodel skill). If it exists, read it -- it already contains table logical names, display names, and column info.
# Check if manifest exists
Test-Path ".datamodel-manifest.json"See ${CLAUDE_PLUGIN_ROOT}/references/datamodel-manifest-schema.md for the full manifest schema.
If no manifest exists, discover custom tables via OData:
$tables = Invoke-RestMethod -Uri "$envUrl/api/data/v9.2/EntityDefinitions?`$select=LogicalName,DisplayName,EntitySetName&`$filter=IsCustomEntity eq true" -Headers $headersFor each discovered table, fetch its custom columns:
$columns = Invoke-RestMethod -Uri "$envUrl/api/data/v9.2/EntityDefinitions(LogicalName='<table>')/Attributes?`$select=LogicalName,DisplayName,AttributeType,RequiredLevel&`$filter=IsCustomAttribute eq true" -Headers $headersShow the user the list of discovered tables with their columns so they can choose which to populate.
Output: List of discovered tables with their columns presented to the user
Goal: Gather user preferences on which tables to populate and how many records to create
Actions:
Use AskUserQuestion to ask which tables they want to populate (use multiSelect: true). List all discovered tables as options.
Use AskUserQuestion to ask how many sample records per table:
| Option | Description |
|---|---|
| 5 records | Quick test -- just enough to verify the setup |
| 10 records | Light demo data for basic testing |
| 25 records | Fuller dataset for realistic demos |
| Custom | Let the user specify a number |
Analyze relationships between selected tables. Parent/referenced tables must be inserted first so their IDs are available for child/referencing table lookups.
Build the insertion order:
Output: Confirmed table selection, record count, and insertion order
Goal: Generate contextually appropriate sample records and get user approval before inserting
Actions:
For each selected table, generate sample records with contextually appropriate values based on column names and types:
jane.doe@example.com, "Phone" -> (555) 123-4567, "Name" -> realistic names)true and false valuesFor each table, show a markdown table previewing the sample records directly in the conversation:
### Project (cr123_project) -- 5 records
| Name | Description | Status | Start Date |
|------|-------------|--------|------------|
| Website Redesign | Modernize the corporate website | 100000000 (Active) | 2025-03-15 |
| Mobile App | Build iOS and Android app | 100000001 (Planning) | 2025-04-01 |
| ... | ... | ... | ... |Show relationship handling: which lookup fields reference which parent table records.
Output: Sample data plan ready for insertion. Proceed directly to Phase 5.
Goal: Execute OData POST calls to create all approved sample records with correct relationship handling
Actions:
Refer to references/odata-record-patterns.md for full patterns.
For each table, get the entity set name (needed for the API URL):
$entityDef = Invoke-RestMethod -Uri "$envUrl/api/data/v9.2/EntityDefinitions(LogicalName='<table>')?`$select=EntitySetName" -Headers $headers
$entitySetName = $entityDef.EntitySetNameFor any picklist/choice columns, query valid option values before insertion:
$picklistMeta = Invoke-RestMethod -Uri "$envUrl/api/data/v9.2/EntityDefinitions(LogicalName='<table>')/Attributes(LogicalName='<column>')/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?`$expand=OptionSet" -Headers $headersUse the actual Value integers from the option set in your sample data.
Insert records into parent/referenced tables first to capture their IDs:
$body = @{
cr123_name = "Sample Record"
cr123_description = "A sample record for testing"
} | ConvertTo-Json
$response = Invoke-RestMethod -Method Post -Uri "$envUrl/api/data/v9.2/<EntitySetName>" -Headers $headers -Body $body -ContentType "application/json"Capture the returned record ID from the OData-EntityId response header or by querying back:
# The ID is in the response headers
# Or query: GET {envUrl}/api/data/v9.2/<EntitySetName>?$filter=cr123_name eq 'Sample Record'&$select=cr123_<table>idStore parent record IDs for use in child table lookups.
For child/referencing tables, use @odata.bind syntax to set lookup fields:
$body = @{
cr123_name = "Child Record"
"cr123_ParentId@odata.bind" = "/<ParentEntitySetName>(<parent_guid>)"
} | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "$envUrl/api/data/v9.2/<ChildEntitySetName>" -Headers $headers -Body $body -ContentType "application/json"Track each insertion attempt:
Refresh the Azure CLI token every 20 records to avoid expiration:
$token = az account get-access-token --resource "$envUrl" --query accessToken -o tsv
$headers["Authorization"] = "Bearer $token"Output: All approved records inserted with parent-child relationships established
Goal: Confirm record counts and present a final summary to the user
Actions:
For each table that was populated, query the record count:
$count = Invoke-RestMethod -Uri "$envUrl/api/data/v9.2/<EntitySetName>?`$count=true&`$top=0" -Headers $headersThe @odata.count field in the response gives the total record count.
Reference:
${CLAUDE_PLUGIN_ROOT}/references/skill-tracking-reference.md
Follow the skill tracking instructions in the reference to record this skill's usage. Use --skillName "AddSampleData".
Present a summary table:
| Table | Records Requested | Records Created | Failures |
|---|---|---|---|
cr123_project (Project) | 10 | 10 | 0 |
cr123_task (Task) | 10 | 9 | 1 |
Include:
After the summary, suggest:
/power-pages:create-site/power-pages:deploy-siteOutput: Verified record counts and summary presented to the user
Before starting Phase 1, create a task list with all phases using TaskCreate:
| Task subject | activeForm | Description |
|---|---|---|
| Verify prerequisites | Verifying prerequisites | Confirm PAC CLI auth, acquire Azure CLI token, verify API access |
| Discover tables | Discovering tables | Read .datamodel-manifest.json or query OData API for custom tables |
| Select tables and configure | Configuring tables | User picks tables, record count, and determine insertion order |
| Generate and review sample data | Generating sample data | Generate contextual sample records, present preview, get user approval |
| Insert sample data | Inserting records | Execute OData POST calls with relationship handling and token refresh |
| Verify and summarize | Verifying results | Confirm record counts, present summary, suggest next steps |
Mark each task in_progress when starting it and completed when done via TaskUpdate. This gives the user visibility into progress and keeps the workflow deterministic.
Begin with Phase 1: Verify Prerequisites
8ccaae8
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.