Creating columns in Dataverse is simple when you do it through the UI, but as soon as you’re working across multiple environments or repeating the same setup, clicking everything manually becomes slow and error-prone. This is where PowerShell comes in handy. In this post, I’ll show you how to create create Columns in Dataverse using PowerShell. It’s perfect for provisioning environments, automating deployments, or just avoiding the randomness of manual configuration. One big bonus: when you create columns through the UI, Dataverse gives them a generated prefix like ab1cd_columnName. With PowerShell, you can set your own consistent project prefix, projectName_columnName, and keep it identical across every environment.
Prerequisites
Before you start creating columns in Dataverse with PowerShell, make sure you have the following in place:
- PowerShell 7+ (recommended)
Most Dataverse and Microsoft Graph–related modules work more reliably in PowerShell 7. If you’re still on Windows PowerShell 5.1, the commands may work, but they might not. - Appropriate Permissions in the Environment
In my example I’ll be using a client credentials approach – then you need a app registration with permissions to Dataverse. But you can also run the scrip as the current user. Just authenticate by runningAdd-PowerAppsAccount– you’ll sign in via a browser window, and then you’re ready to go. - A Dataverse Environment Ready to Target
You’ll need the environment URL.
Setting up script variables
Before doing anything else, you need a few key variables in place: your app registration details, tenant info, and the Dataverse environment URL. These values allow the script to authenticate using client credentials and point the API requests to the correct Dataverse instance.
Keep in mind that client secrets should not be stored directly in your script if this code is going into a repo or running somewhere shared. Put them in a Key Vault, environment variable, or local settings file instead.
$clientId = "YOUR_ID_HERE" $clientSecret= "YOUR_SECRET_HERE" #If your code is going to be deployed someweher, or kept in a repository, the secret should be kept in a key-vaul, or local settings file, not as text in your script. $clientId = "YOUR_ID_HERE" $tenantId = "YOUR_TENANT_ID" $envUrl = "URL_TO_YOUR_ENV_HERE" # This will be something like this: https://org<something>.crm4.dynamics.com/ $authUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" $tableName = "LOGICAL_NAME_OF_YOUR_DATAVERSETABLE"
Prepare the authentication body and get token
To create columns in Dataverse using PowerShell Dataverse requires an OAuth 2.0 access token to authorize your API requests. Here you build the token request body, including the scope for your environment, and then request the token using Invoke-RestMethod.
$body = @{
client_id = $clientId
client_secret = $clientSecret
scope = "https://$($envUrl.Replace('https://', ''))/.default"
grant_type = "client_credentials"
}
Request the token
With the authentication body prepared, you can request the token.
This token is what allows your script to make authenticated API calls to Dataverse.
$response = Invoke-RestMethod -Method Post -Uri $authUrl -ContentType "application/x-www-form-urlencoded" -Body $body $accessToken = $response.access_token
Prepare the headers for the requests
Once you have the access token, it must be included in every API request. These headers tell Dataverse what format you’re sending data in and what API version you want to use.
$authHeader = @{
Authorization = "Bearer $accessToken"
"Content-Type" = "application/json"
"OData-MaxVersion" = "4.0"
"OData-Version" = "4.0"
Accept = "application/json"
}
Define your columns
This is where the real work happens. You’re creating metadata definitions for new Dataverse columns.One of the biggest advantages of creating columns this way is that you control the prefix.
Instead of Dataverse giving you a random environment-based prefix (ab1cd_columnName), you can use a project-specific prefix such as projectName_columnName. This means your schema stays consistent across all environments, super useful for ALM and long-term maintainability.
String column
This creates a standard text column. Notice the “SchemaName”, because you’re creating the column with PowerShell, you can define your own prefix (e.g., projectName_). This keeps your schema consistent across environments, unlike the auto-generated prefixes Dataverse creates in the UI.
$stringColumn = @{
"@odata.type" = "Microsoft.Dynamics.CRM.StringAttributeMetadata"
"AttributeTypeName" = @{ "Value" = "StringType" }
"SchemaName" = "projectName_myStringColumnName"
"DisplayName" = @{
"LocalizedLabels" = @(
@{
"Label" = "My string column name"
"LanguageCode" = 1033
}
)
}
"Description" = @{
"LocalizedLabels" = @(
@{
"Label" = "My string column name"
"LanguageCode" = 1033
}
)
}
"MaxLength" = 250
}
Boolean column
Boolean columns work similarly but include an OptionSet definition for the Yes /No labels. Again, you can define your own schema prefix, which keeps things clean across dev/test/prod environments.
$booleanColumn = @{
"@odata.type" = "Microsoft.Dynamics.CRM.BooleanAttributeMetadata"
"SchemaName" = "projectName_myBooleanColumn"
"DisplayName" = @{
"LocalizedLabels" = @(
@{
"Label" = "This is a cool project"
"LanguageCode" = 1033
}
)
}
"Description" = @{
"LocalizedLabels" = @(
@{
"Label" = "This column will say if the project is cool or not"
"LanguageCode" = 1033
}
)
}
"RequiredLevel" = @{
"Value" = "None"
}
"OptionSet" = @{
"TrueOption" = @{
"Label" = @{
"LocalizedLabels" = @(
@{
"Label" = "Yes"
"LanguageCode" = 1033
}
)
}
"Value" = 1
}
"FalseOption" = @{
"Label" = @{
"LocalizedLabels" = @(
@{
"Label" = "No"
"LanguageCode" = 1033
}
)
}
"Value" = 0
}
}
}
Doing the request to create the column
Finally, you send a POST request to the Dataverse Web API, targeting the specific table’s attribute collection.
This is what actually creates the column inside your Dataverse environment.
Invoke-RestMethod -Method Post -Uri "$envUrl/api/data/v9.2/EntityDefinitions(LogicalName='$tableName')/Attributes" -Headers $authHeader -Body ($stringColumn| ConvertTo-Json -Depth 10)
Repeat this step for any additional column definitions you want to add—like your boolean column.
Summary
Creating columns in Dataverse using PowerShell gives you full control, consistency across environments, and a repeatable way to manage changes without clicking through the UI. By defining your own schema names and prefixes, your solution becomes more maintainable and avoids the random prefixes Dataverse generates automatically.
Once the authentication, headers, and column metadata are in place, adding new fields becomes a simple API call. This approach fits perfectly into ALM pipelines, automated deployments, or any project where you want predictable and version-controlled Dataverse configuration.
Resources
- Quick Start Web API with PowerShell and Visual Studio Code (Microsoft docs)
- Create and update column definitions using the Web API (Microsoft docs)
- Use PowerShell and Visual Studio Code with the Dataverse Web API
If you are interested in Power Platform Development you might also like my other blogposts in this category.
Also, if you have any feedback or questions, please let me know in the comments below. 🙂
Thank you for reading, and happy coding!
/Eli
If you want to support my content you can
