# PowerShell For Dataverse Developers

CI/CD has become an integral part of ALM these days and PowerShell is the first choice of scripting, Dataverse projects are no exception. For Setting up CI/CD for Dataverse already many extensions are available on [Azure DevOps Marketplace](https://marketplace.visualstudio.com/azuredevops/). Here in this article, we will see how to perform different actions against Dataverse data using PowerShell which can be used further in CI/CD pipelines or other places.

## Install required modules

We will use [Microsoft.Xrm.Data.PowerShell](https://github.com/seanmcne/Microsoft.Xrm.Data.PowerShell) module created by [Sean McNellis](https://github.com/seanmcne) which is a wrapper around official Microsoft modules and makes the job a lot easier.

You'd need to run PowerShell as admin to install a new module, then execute the below command. It would ask for confirmation before installing, enter 'Y' or 'A' to install.

```bash
Install-Module "Microsoft.Xrm.Data.PowerShell"
```

![Install-Module "Microsoft.Xrm.Data.PowerShell"](https://cdn.hashnode.com/res/hashnode/image/upload/v1670768034072/QcxJRKMW1.png align="center")

## Making a connection to an environment

The Get-CrmConnection command creates a connection to the environment. If using it locally then can go for interactive mode or non-interactive mode using a connection string. We'll store the connection object to a variable $Conn.

### Interactive Mode

Execute the below command, it would show an interactive login prompt where you can log in using your credentials and select desired organization you wish to connect.

```bash
$Conn = Get-CrmConnection -InteractiveMode
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1670770674457/_CzNzT02L.png align="center")

After a successful connection, you can see the contents of the $Conn object like below if you wish to.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1670770485383/J2P1tvcQb.png align="center")

### Non-interactive Mode

For a non-interactive connection, we need to prepare a connection string by acquiring the client id/secret from azure. Call Get-CrmConnection with the -ConnectionString parameter.

```bash
$Conn = Get-CrmConnection -ConnectionString "AuthType=ClientSecret;url=https://orgc28637dd.crm8.dynamics.com;ClientId=f8a6e260-4725-b27f-2870343ef742;ClientSecret=HLT8QoLoPYT9rzkj1rrqi.R1COGLZ.clM"
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671282286884/9SIorMWY1.png align="center")

## Create new record

New-CrmRecord is used to create new records, this accepts -EntityLogicalName & Fields parameter along with -conn. This returns Guid of created record.

```bash
$ContactId = New-CrmRecord -conn $Conn -EntityLogicalName contact -Fields @{"firstname"="Ashish";"lastname"="Vishwakarma";"jobtitle"="Senior Consultant"}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671374777879/M1uN8jMYH.png align="center")

## Retrieve record by Id

To retrieve a record using Guid, Get-CrmRecord need to be called with EntityLogicalName, Id & Fields to retrieve. The connection object also needs to be passed in the -conn parameter.

```bash
$ContactRecord = Get-CrmRecord -conn $Conn -EntityLogicalName contact -Id "9869dab8-0c7e-ed11-0000-6045bdea00fb" -Fields fullname,jobtitle
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671284054765/uUOcBTgTg.png align="center")

## Retrieve records based on the condition

To retrieve records based on some condition Get-CrmRecords is used with -Filter\* parameters. This uses fetchXml internally, record values can be accessed via the CrmRecords property.

```bash
$ConsultantRecords = Get-CrmRecords -conn $Conn -EntityLogicalName contact -Fields fullname,jobtitle -FilterAttribute jobtitle -FilterOperator eq -FilterValue "Consultant"

$ConsultantRecords.CrmRecords
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671313960693/2HukGGCkc.png align="center")

## Query records using fetchXml

To query records with fetchXml Get-CrmRecordsByFetch is used with the -Fetch parameter which accepts fetchXml query.

```bash
$FetchXml = "<fetch mapping='logical'>
   <entity name='account'>
      <attribute name='accountid'/>
      <attribute name='name'/>
   </entity>
</fetch>  
"

$FetchXmlRecords = Get-CrmRecordsByFetch -conn $Conn -Fetch $FetchXml
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671364945265/Erb5gJYy4.png align="center")

## Update records

Set-CrmRecord is used to update an existing record.

```bash
Set-CrmRecord -conn $Conn -EntityLogicalName contact -Id 9869dab8-0c7e-ed11-81ac-6045bdea00fb -Fields @{ "firstname" = "Avinash" }
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671371190106/-wbNY4kL5.png align="center")

If updating some property of already retrieved record then the below syntax can be used alternatively since it has metadata information already.

```bash
$ContactRecord = Get-CrmRecord -conn $Conn -EntityLogicalName contact -Id 9869dab8-0c7e-ed11-81ac-6045bdea00fb -Fields fullname,jobtitle
$ContactRecord.jobtitle = "Manager"
Set-CrmRecord -conn $Conn -CrmRecord $ContactRecord
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671372043450/wo1WnGEOF.png align="center")

If you want to update a property using an already retrieved object but the property is not already present in the object, then we can first use -Add-Member to set the property and use this in Set-Record.

```bash
$ContactRecord | Add-Member -MemberType NoteProperty -Name lastname -Value "Sharma"
Set-CrmRecord -conn $Conn -CrmRecord $ContactRecord
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671372689680/B9SVqQSYn.png align="center")

## Delete a record

Remove-CrmRecord is used to delete records. Like Set-CrmRecord this also can be used either with Id or record object. See the below examples.

```bash
Remove-CrmRecord -conn $Conn -EntityLogicalName contact -Id 9969ef91-e27e-ed11-81ac-002248d60670
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671378043007/HUhWB0HMO.png align="center")

```bash
Remove-CrmRecord -conn $Conn -CrmRecord $ContactRecord
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1671378155457/tsxuFaMDa.png align="center")
