Разработка
25
Ноя
0

PowerShell и CRM

Иногда в процессе тестирования требуется воспроизвести определенную ситуацию (например, создания записи), но не через интерфейс системы. Одним из вариантов является написание консольки или какая-либо более мощная разработка. Но на это требуется время и ресурсы разработчика. Но есть вариант, который вполне под силам освоить и консультантам – PowerShell.

С одной стороны, не нужно разбираться в компилируемых языках и знать, как работать в Visual Studio, с другой стороны командную строку и скрипты может освоить каждый и при этом Вы получаете полноценный инструмент программного создания записей (и других манипуляций).

PowerShell сам по себе с CRM работать не умеет. Вместо этого он дергает методы, написанные на C# и скомпилированные в отдельные DLL-библиотеки. Уже готовые библиотеки поставляет MS (CRM SDK), другие можно написать самим.

Рассмотрим, что поставляет нам MS…

Но прежде чем начнем писать полезный код, обеспечим себе более-менее комфортную работу…

Инструменты

Для запуска PowerShell-скриптов можно использовать стандартное консольное приложение powershell.exe. Но гораздо удобнее для этого использовать более удобный графический интерфейс, более адоптированный для написания кода: выдающие подсказки, подсвечивающие код, позволяющие выполнять код прямо из редактора и т.д. Для этих целей можно использовать две бесплатные утилиты…

PowerShell ISE

Windows PowerShell ISE – бесплатная графическая среда разработки для PowerShell от Microsoft. На Windows 8 и Windows Server 2012 PowerShell ISE уже установлена по умолчанию – можно сразу запустить следующей командой:

powershell_ise.exe

На Windows 2008 R2 PowerShell ISE установлен, но ее необходимо активировать следующей командой:

Import-Module ServerManager Add-Windowsfeature PowerShell-ISE

На Windows 7 и Windows Server 2008 SP1 PowerShell ISE должна быть установлена отдельно.

PowerGUI

PowerGUI – более мощная и бесплатная IDE (но уже от DELL). Скачать ее можно отсюда: http://en.community.dell.com/techcenter/powergui/m/bits/20439049

Подготовка

Прежде чем начать писать полезный код необходимо обеспечить следующие требования с окружающей среде:

  • Версия PowerShell должна быть 3.0 и более. Проверить версию PowerShell можно с помощью следующего скрипта:
    # Get PowerShell version
    $PSVersionMajor = $Host.Version.Major;
    $PSVersionMinor = $Host.Version.Minor;
    
    throw "PowerShell version: $PSVersionMajor.$PSVersionMinor";
    
  • Политика выполнения PowerShell-скриптов должна быть достаточно «мягкой»: AllSigned или Unrestricted. По умолчанию выполнение скриптов блокируется. Проверить текущую политику выполнения PowerShell можно с помощью следующего скрипта:
    # Get Execution policy
    $ExecutionPolicy = Get-ExecutionPolicy;
    throw $ExecutionPolicy;
    

    Чтобы разблокировать выполнение PowerShell-скриптов выполните (под админом) следующий скрипт:

    Set-ExecutionPolicy Unrestricted -Scope CurrentUser


Кажется, все готово… можем шкодить 🙂

Подключаемся к организации CRM

Сначала нужно установить соединение с CRM.

# Load SDK assemblies
$PSScriptRoot = "C:\SDK\Bin";

Add-Type -Path "$PSScriptRoot\Microsoft.Xrm.Sdk.dll";
Add-Type -Path "$PSScriptRoot\Microsoft.Xrm.Client.dll";
Add-Type -Path "$PSScriptRoot\Microsoft.Crm.Sdk.Proxy.dll";

# Configure CRM connection
$url = "http://crm2015/superfirma";
$login = "Administrator";
$pwd = "1qaz@WSX";
    
$crmConnection = [Microsoft.Xrm.Client.CrmConnection]::Parse("Url=$url; Username=$login; Password=$pwd");

$service = New-Object -TypeName Microsoft.Xrm.Client.Services.OrganizationService -ArgumentList $crmConnection;

Тут все просто:

  • Чтобы иметь доступ к классам CRM, мы должны загрузить сборки SDK CRM в текущий сеанс Powershell;
  • Устанавливаем соединение с CRM;
  • Инстанцируем объект OrganizationService.

После этого через $service можем выполнять различные операции…

З.Ы. Когда пишите PowerShell-скрипты в ISE или командной строке учтите, что переменные и типы объявленные в текущем сеансе остаются в нем пока не будет закрыто ISE или командная строка. Поэтому не забывайте их закрывать между выполнениями.

Создание записи

# Instanciate new account Entity object
$account = New-Object -TypeName Microsoft.Xrm.Sdk.Entity -ArgumentList "account";
$account["name"] = "PowerShell is great!23";
$optionSetValue = New-Object -TypeName "Microsoft.Xrm.Sdk.OptionSetValue" -ArgumentList 3;
$account["ownershipcode"]= [Microsoft.Xrm.Sdk.OptionSetValue] $optionSetValue;

# Create an account and retrieve new ID
$id = $service.Create($account);


Поиск записи

function Get-Account
{
     PARAM
    (
        [parameter(Mandatory=$true)]$accountNumber
    )

    $query = New-Object -TypeName Microsoft.Xrm.Sdk.Query.QueryExpression -ArgumentList "account";
    $query.Criteria.AddCondition("accountnumber", [Microsoft.Xrm.Sdk.Query.ConditionOperator]::Equal, $accountNumber);
    $query.ColumnSet.AddColumn("name");
    $results = $service.RetrieveMultiple($query);
    $records = $results.Entities;

    if($records.Count -eq 1)
    {
        return $records[0];
    }
    Write-Host -ForegroundColor Red "Record not found : $id"
    return $null;
}

$acc = Get-Account "ACSHN2S4";
$acc;

RetrieveMultiple с разбивкой на страницы

function Get-Account
{
     PARAM
    (
        [parameter(Mandatory=$true)]$accountNumber
    )

    $query = New-Object -TypeName Microsoft.Xrm.Sdk.Query.QueryExpression -ArgumentList "account";
    $query.Criteria.AddCondition("accountnumber", [Microsoft.Xrm.Sdk.Query.ConditionOperator]::Equal, $accountNumber);
    $query.ColumnSet.AddColumn("name");
    $results = $service.RetrieveMultiple($query);
    $records = $results.Entities;

    if($records.Count -eq 1)
    {
        return $records[0];
    }
    Write-Host -ForegroundColor Red "Record not found : $id"
    return $null;
}

$acc = Get-Account "ACSHN2S4";
$acc;
RetrieveMultiple с разбивкой на страницы
function Get-Multiple-Records
{
    PARAM
    (
        [parameter(Mandatory=$true)]$service,
        [parameter(Mandatory=$true)]$query
    )

    $pageNumber = 1;

    $query.PageInfo = New-Object -TypeName Microsoft.Xrm.Sdk.Query.PagingInfo;
    $query.PageInfo.PageNumber = $pageNumber;
    $query.PageInfo.Count = 1000;
    $query.PageInfo.PagingCookie = $null;

    $records = $null;
    while($true)
    {
        $results = $service.RetrieveMultiple($query);
                
        Write-Progress -Activity "Retrieve data from CRM" -Status "Processing record page : $pageNumber" -PercentComplete -1;
        if($results.Entities.Count -gt 0)
        {
            if($records -eq $null)
            {
                $records = $results.Entities;
            }
            else
            {
                $records.AddRange($results.Entities);
            }
        }
        if($results.MoreRecords)
        {
            $pageNumber++;
            $query.PageInfo.PageNumber = $pageNumber;
            $query.PageInfo.PagingCookie = $results.PagingCookie;
        }
        else
        {
            break;
        }
    }
    return $records;
}

$query = New-Object -TypeName Microsoft.Xrm.Sdk.Query.QueryExpression -ArgumentList "account";
$query.ColumnSet.AddColumn("name");
$query.Criteria.AddCondition("accountnumber", [Microsoft.Xrm.Sdk.Query.ConditionOperator]::NotNull);
$query.AddOrder("name", [Microsoft.Xrm.Sdk.Query.OrderType]::Ascending);

$accounts = Get-Multiple-Records $service $query;

$current = 0;
$total = $accounts.Count;

foreach($account in $accounts)
{
    $accountName = $account.Attributes["name"];
    $current++;
    $percent = ($current/$total)*100;
    
    Write-Progress -Activity "Account data management" -Status "[$current/$total] Processing account '$accountName' ..." -PercentComplete $percent;
    Write-Host "Account : $accountName" -ForegroundColor Yellow;       
}

  • В этом примере мы получим все записи Организаций, у которым задан и сортируем их по имени. При этом отбираем их по 1000 штук и добавляем в общий массив;
  • Возвращенный результат просматриваем по очереди и выводим в консоль.

Обновление записи

# Instanciate new account Entity object
$accountToUpdate = New-Object -TypeName Microsoft.Xrm.Sdk.Entity -ArgumentList "account";
$accountToUpdate.Id = "da553cfd-1892-e511-80c1-000c291afb9d";
$accountToUpdate["name"] = "CRM and PowerShell are greats!"

# Update account
$service.Update($accountToUpdate);

Удаление записи

# Delete account
$service.Delete("account", $id);

Назначение записи

function Assign-Record
{
    PARAM
    (
        [parameter(Mandatory=$true)]$recordReference,
        [parameter(Mandatory=$true)]$ownerReference
    )

    $assignRequest = New-Object -TypeName Microsoft.Crm.Sdk.Messages.AssignRequest;
    $assignRequest.Target = $recordReference;
	$assignRequest.Assignee = $ownerReference;

    $result = $service.Execute($assignRequest);
}

$user = New-Object -TypeName Microsoft.Xrm.Sdk.Entity -ArgumentList "systemuser";
$user.Id = "92bfe9bc-a83b-e511-80b7-000c291afb9d";

$account = New-Object -TypeName Microsoft.Xrm.Sdk.Entity -ArgumentList "account";
$account.Id = "da553cfd-1892-e511-80c1-000c291afb9d";

Assign-Record $account.ToEntityReference() $user.ToEntityReference();
Комментарии (0)

*

code