Perform CRUD Operations in Dynamics CRM Using PowerShell

Introduction

PowerShell, a robust scripting language, proves highly effective for establishing connections with Dynamics CRM and executing CRUD operations (Create, Retrieve, Update, and Delete records). In this article, we will explore the process of connecting to Dynamics CRM using PowerShell and carrying out fundamental CRUD operations. Utilizing PowerShell scripting for Dynamics CRM can be applied in various use cases across business processes.

Use Cases

  1. Routine Data Maintenance: Conduct regular updates or deletions of records based on specific criteria, guaranteeing the precision and relevance of data.
  2. Efficient Bulk Record Creation: Simplify the simultaneous creation of multiple records, saving time and reducing manual workload.
  3. Scheduled Automation Tasks: Plan the execution of PowerShell scripts at specific times to carry out routine tasks, such as record updates or report generation.
  4. Tailored Custom Business Logic: Deploy personalized business logic using PowerShell scripts, enabling automation that precisely aligns with organizational requirements.
  5. Automated Data Extraction for Reporting: Streamline the retrieval of data from Dynamics CRM for reporting purposes, ensuring the availability of up-to-date information for analysis.
  6. Automated User Management: Streamline processes for user provisioning or deactivation within Dynamics CRM, ensuring that user access remains in accordance with organizational needs.
  7. Effective Error Handling and Logging: Integrate robust mechanisms for error handling and logging features into scripts to monitor and troubleshoot issues, thereby enhancing the dependability of automated processes.
  8. Automated Security Configuration: Implement the automation of security configurations, permissions, and access controls within Dynamics CRM to ensure data security and compliance.

Setup and Demo for basic CRUD operations

Prerequisites: We need to have the "Microsoft.Xrm.Data.PowerShell" module installed on our system to perform CRUD operations.

Step 1. Open Windows PowerShell ISE

Open Windows PowerShell ISE and Paste below code snippet.

$Module = "Microsoft.Xrm.Data.PowerShell"
Install-Module -Name $Module -Scope CurrentUser -AllowClobber -Force
Import-Module -Name $Module -Force

The above commands will perform the below operation.

  • Assigning Variable: The statement '$Module = "Microsoft.Xrm.Data.PowerShell"' assigns the module name to the variable '$Modul'.
  • Module Installation: The command 'Install-Module -Name $Module -Scope CurrentUser -AllowClobber -Force' installs the designated module for the current user, permitting the overwriting of existing modules ('-AllowClobber') and compelling the installation ('-Force').
  • Module Import: The command 'Import-Module -Name $Module -Force' imports the installed module, enabling access to its functionality within the PowerShell session (the '-Force' flag is employed to enforce the import).

On the left-hand side, under the command pane, we can see all the commands related to the installed module.

Commands

Now let's discuss some of these commands.

Step 2. Setup connection to Dynamics CE environment

There are multiple methods for connecting to an environment.

a. Using Username and Password

$conn = Get-CrmConnection -ConnectionString "AuthType=Office365;Username=<username>;Password=<password>;Url=<environment url>"
Write-Host "Connected to env" $conn.ConnectedOrgFriendlyName

The above set of commands uses the Get-CrmConnection cmdlet with a connection string containing Office 365 authentication details, including the username, password, and environment URL.

Note: The above command will not work in case MFA is enabled. Please refer to this link to Disable MFA: Disabling Multifactor Authentication in Microsoft-related Services (c-sharpcorner.com)

b. Using Interactive Mode

$conn = Get-CrmConnection -InteractiveMode
Write-Host "Connected to env" $conn.ConnectedOrgFriendlyName

The above set of commands interactively prompts the user to provide essential details for establishing a connection to Dynamics CRM, it uses -InteractiveMode parameter in conjunction with the Get-CrmConnection cmdlet.

A pop will appear after a successful run as shown below.

Login

c. Using Service Principal User

Prerequisite: The application should be registered with Dynamics CRM API permission in Azure Portal and the application user should have sufficient roles to perform desired operations.

$conn = Get-CrmConnection -ConnectionString "AuthType=ClientSecret;Url=<URL>;ClientId=<ClientId>;ClientSecret=<ClientSecret>"
Write-Host "Connected to env" $conn.ConnectedOrgFriendlyName

The above set of commands employs the Get-CrmConnection cmdlet with a connection string containing details for Client Secret authentication, including the CRM URL, client ID, and client secret.

This is a recommended way of connecting to the Dynamics environment securely and can be easily implemented in automation pipelines.

Step 3. Now let's Perform all CRUD operations using the $conn object

a. Create a contact record with the following datatypes: Lookup, Date& Time, Text, Boolean, and Option Set

Below given set of commands below will create a new contact record in the target environment. 

Note. Values for Required fields should always be passed while creating a new record.

# Define the field values for the new contact record
$contactFieldValues = @{
    "firstname" = "Saksham";
    "lastname" = "Gupta";
    "birthdate" = [datetime]"2024-06-22";
    "emailaddress1" = "[email protected]";
    "creditonhold" = $true;  # Boolean field
    "preferredcontactmethodcode" = New-CrmOptionSetValue -Value 1  # Option Set value (adjust based on your CRM configuration)
    "parentcustomerid" = New-Object Microsoft.Xrm.Sdk.EntityReference("account", "<AccountGuid>")  # Replace with the actual Account Id
}

# Create a new contact record in Dynamics CRM
$contactGuid = New-CrmRecord -conn $conn -EntityLogicalName contact -Fields $contactFieldValues
  • "birthdate": Uses the [datetime] type casting for a valid date.
  • "creditonhold": Set to $true a boolean field.
  • "preferredcontactmethodcode": Utilized New-CrmOptionSetValue to specify the option set value.
  • "parentcustomerid": Employed New-Object Microsoft.Xrm.Sdk.EntityReference to create the lookup field with the actual Account Id.

b. Retrieve record(s) from the target environment.

The below set of commands will retrieve records using a filter on a single column.

This code retrieves contact records where the fullname is "Saksham Gupta" and then iterates through each retrieved contact, displaying the parentcustomerid for each one.

# Retrieve contacts with the fullname "Saksham Gupta" and fetch the parentcustomerid field
$retrieveContacts = Get-CrmRecords -conn $conn -EntityLogicalName contact -FilterAttribute fullname -FilterOperator "eq" -FilterValue "Saksham Gupta" -Fields parentcustomerid

# Loop through retrieved contacts and display the parentcustomerid
foreach ($contact in $retrieveContacts.CrmRecords) {
    $contact.parentcustomerid
}

Retrieve records using fetchxml with the below set of commands.

The below code loops through the retrieved contacts and displays the fullname, parentcustomerid, emailaddress1, and contactid attributes for each contact. 

$fetchXml = @"
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
  <entity name="contact">
    <attribute name="fullname"/>
    <attribute name="parentcustomerid"/>
    <attribute name="emailaddress1"/>
    <attribute name="contactid"/>
    <order attribute="fullname" descending="false"/>
    <filter type="and">
      <condition attribute="statecode" operator="eq" value="0"/>
      <condition attribute="firstname" operator="eq" value="Saksham"/>
      <condition attribute="lastname" operator="eq" value="Gupta"/>
    </filter>
  </entity>
</fetch>
"@

# Retrieve contacts using FetchXML
$fetchContacts = Get-CrmRecordsByFetch -conn $conn -Fetch $fetchXml

# Loop through retrieved contacts and display selected attributes
foreach ($contact in $fetchContacts.CrmRecords) {
    Write-Host "Full Name: $($contact.fullname)"
    Write-Host "Parent Customer ID: $($contact.parentcustomerid)"
    Write-Host "Email Address: $($contact.emailaddress1)"
    Write-Host "Contact ID: $($contact.contactid)"
    Write-Host "-----------------------"
}

c. For existing records, we can perform an update operation using the "Microsoft.Xrm.Data.PowerShell" module.

This script updates the specified contact record with the values provided in the $updateContactRecord . The Id parameter is used to identify the contact record to be updated.

$updateContactRecord = @{
    "firstname" = "Test";
    "lastname" = "User";
    "emailaddress1" = "[email protected]";
}

# Create a new contact record in Dynamics CRM
$newContactGuid = Set-CrmRecord -conn $conn -EntityLogicalName contact -Id $contactGuid -Fields $updateContactRecord

d. At last if required we can perform a Delete operation as well on CRM records.

This command will remove the contact record identified by the specified $contactGuid from the Dynamics CRM system.

# Delete a contact record by record id
Remove-CrmRecord -conn $conn -EntityLogicalName contact -Id $contactGuid

Below is the complete code for reference.

$Module = "Microsoft.Xrm.Data.PowerShell"
Install-Module -Name $Module -Scope CurrentUser -AllowClobber -Force
Import-Module -Name $Module -Force


$conn = Get-CrmConnection -ConnectionString "AuthType=ClientSecret;Url=<URL>;ClientId=<clientID>;ClientSecret=<clientsecret>"
Write-Host "Connected to env" $conn.ConnectedOrgFriendlyName

# Define the field values for the new contact record
$contactFieldValues = @{
    "firstname" = "Saksham";
    "lastname" = "Gupta";
    "birthdate" = [datetime]"2024-06-22";
    "emailaddress1" = "[email protected]";
    "creditonhold" = $true;  # Boolean field
    "preferredcontactmethodcode" = New-CrmOptionSetValue -Value 1  # Option Set value (adjust based on your CRM configuration)
    "parentcustomerid" = New-Object Microsoft.Xrm.Sdk.EntityReference("account", "831fbbb8-c79b-ee11-a569-002248d5d2d5")  # Replace with the actual Account Id
}

# Create a new contact record in Dynamics CRM
$contactGuid = New-CrmRecord -conn $conn -EntityLogicalName contact -Fields $contactFieldValues

# Retrieve contacts with the fullname "Saksham Gupta" and fetch the parentcustomerid field
$retrieveContacts = Get-CrmRecords -conn $conn -EntityLogicalName contact -FilterAttribute fullname -FilterOperator "eq" -FilterValue "Saksham Gupta" -Fields parentcustomerid

# Loop through retrieved contacts and display the parentcustomerid
foreach ($contact in $retrieveContacts.CrmRecords) {
    $contact.parentcustomerid
}

$fetchXml = @"
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
  <entity name="contact">
    <attribute name="fullname"/>
    <attribute name="parentcustomerid"/>
    <attribute name="emailaddress1"/>
    <attribute name="contactid"/>
    <order attribute="fullname" descending="false"/>
    <filter type="and">
      <condition attribute="statecode" operator="eq" value="0"/>
      <condition attribute="firstname" operator="eq" value="Saksham"/>
      <condition attribute="lastname" operator="eq" value="Gupta"/>
    </filter>
  </entity>
</fetch>
"@

# Retrieve contacts using FetchXML
$fetchContacts = Get-CrmRecordsByFetch -conn $conn -Fetch $fetchXml

# Loop through retrieved contacts and display selected attributes
foreach ($contact in $fetchContacts.CrmRecords) {
    Write-Host "Full Name: $($contact.fullname)"
    Write-Host "Parent Customer ID: $($contact.parentcustomerid)"
    Write-Host "Email Address: $($contact.emailaddress1)"
    Write-Host "Contact ID: $($contact.contactid)"
    Write-Host "-----------------------"
}


$updateContactRecord = @{
    "firstname" = "Test";
    "lastname" = "User";
    "emailaddress1" = "[email protected]";
}

# Update contact record in Dynamics CRM
Set-CrmRecord -conn $conn -EntityLogicalName contact -Id $contactGuid -Fields $updateContactRecord

# Delete a contact record by record id
Remove-CrmRecord -conn $conn -EntityLogicalName contact -Id $contactGuid

Conclusion

In this article, we discussed how PowerShell can be effectively used for automating tasks in Dynamics CRM, from creating and updating records to retrieving and deleting them. Proper formatting, correct data types, and accurate attribute names are crucial for successful operations. Always ensure accurate authentication details and handle errors to enhance the reliability of scripts. Please feel free to reach out in case any doubts or clarifications are required.


Similar Articles