Pages

Thursday, November 9, 2017

PowerShell - MS Dynamics CRM CRUD Operations

Please refer Read App.Config -
Please refer Connect MS Dynamics CRM

$crm_service = Invoke-CRMConn -OrganizationUrl $crm_organization_url -UserName $crm_username -Password $crm_password

## 1. To test the connection, check who you are:
function WhoAMI() {
    $request = new-object Microsoft.Crm.Sdk.Messages.WhoAmIRequest
    $crm_service.Execute($request)

    <#
    UserId         : 0dc96a70-952d-e611-80f0-0050568c6c1c
    BusinessUnitId : a6099f28-952d-e611-80ec-0050568c6c1c
    OrganizationId : 0d67a31e-952d-e611-80ec-0050568c6c1c
    ResponseName   : WhoAmI
    Results        : {[UserId, 0dc96a70-952d-e611-80f0-0050568c6c1c], [BusinessUnitId, a6099f28-0caf-e611-80ec-0050568c6c1c],
                     [OrganizationId, 0d67a31e-0caf-e611-80ec-0050568c6c1c]}
    ExtensionData  : System.Runtime.Serialization.ExtensionDataObject
    #>
}

PowerShell - Connect MS Dynamics CRM

## create crm connction function, call this function with arguments  OrganizationURL, UserName, Password
function Invoke-CRMConn {
    ## pass arguments OrganizationURL, UserName, Password
    [CmdletBinding()]
    param(
        [Parameter(Position=0, Mandatory=$true)] [string]$OrganizationURL,
        [Parameter(Position=1, Mandatory=$true)] [string]$UserName,
        [Parameter(Position=2, Mandatory=$true)] [string]$Password
    )

    ## get directory path
    $current_directory =  $(Get-Item ($MyInvocation.ScriptName)).DirectoryName
   
    ## load crm & xrm dll
    $xrm_dll = $current_directory + "/microsoft.xrm.sdk.dll"
    $crm_dll = $current_directory + "/microsoft.crm.sdk.proxy.dll"
    [void][System.Reflection.Assembly]::LoadFile($xrm_dll)
    [void][System.Reflection.Assembly]::LoadFile($crm_dll)
    [void][System.Reflection.Assembly]::LoadWithPartialName("system.servicemodel")

    ## create credentials
    $clientCredentials = new-object System.ServiceModel.Description.ClientCredentials
    $clientCredentials.UserName.UserName = $UserName
    $clientCredentials.UserName.Password = $Password
   
    ## create  organization service proxy 
    $service = new-object Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy($OrganizationURL, $null, $clientCredentials, $null)
   
    ## use default crm time out or set 5 minutes of timeout.
    #$service.Timeout = new-object System.Timespan(0, 5, 0)

    ## return service
    return $service
}

## test the service using who i am request
$service1 = Invoke-CRMConn -OrganizationURL "https://dns.com/XRMServices/2011/Organization.svc" -UserName 'test@dns.com' -Password ABC123!@#'
$request = new-object Microsoft.Crm.Sdk.Messages.WhoAmIRequest
$service1.Execute($request)

<#
UserId             : 123ddfa0-9534-f234-8780-78900568c2fc0
BusinessUnitId : 456a043cf-0c34-e234-878c-78900568c6c1c
OrganizationId : 7895b3c2-0c34f-e234-878c-7890568c6c1c
ResponseName   : WhoAmI
Results        : {[UserId, 123ddfa0-952d-f234-8780-7890568c6c1c], [BusinessUnitId, 456a043cf-0caf-e234-8780-7890568c6c1c],
                 [OrganizationId, 7895b3c2-0caf-e234-8780-7890568c6c1c]}
ExtensionData  : System.Runtime.Serialization.ExtensionDataObject
#>

PowerShell - Read App.config

## get current directory
$current_directory =  $(Get-Item ($MyInvocation.MyCommand.Path)).DirectoryName

## $MyInvocation.MyCommand.Path won't work if you call inside the function.
## so use ScriptName to get currect directory
$current_directory =  $(Get-Item ($MyInvocation.ScriptName)).DirectoryName

## path of config file
$app_config_path = $current_directory + "\App.config"

## reading configuration file
$xml_doc = [Xml](Get-Content $app_config_path)

## get appsettings value
$app_nodes = $xml_doc.configuration.appSettings.add
$url = ($app_nodes | where {$_.key -eq 'Url'}).value
$username = ($app_nodes | where {$_.key -eq 'UserName'}).value
$password = ($app_nodes | where {$_.key -eq 'Password'}).value

## get dbconnection setting
$con_nodes = $xml_doc.configuration.connectionStrings.add
$db_con = ($con_nodes | where {$_.name -eq 'DBConnectionString'}).connectionString

## display value
Write-Host  $url
Write-Host  $username
Write-Host  $password
Write-Host  $db_con

<#
App.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="Url" value="https://dns.com/Services/2017/Organization.svc" />
    <add key="UserName" value="mak@dns.com"/>
    <add key="Password" value="ABC123456!@#"/>
  </appSettings>
  <connectionStrings>
    <add name="DBConnectionString" connectionString="Data Source=MAK12345.dns.com,1044;Initial Catalog=COS_SVC;User ID=root; Password=DEF456$%^;" providerName="System.Data.SqlClient"/>
  </connectionStrings>
</configuration>
#>

Wednesday, November 8, 2017

PowerShell Dictionary

1.Create empty dictionary
$contacts = @{}

2.Add key,value item
## Way 1:
$key = 1
$value = 'CRM'
$contacts.add( $key, $value )

## Way 2:
$contacts.add( 2, 'C#' )

## Way 3:
$contacts[3]='.NET'

## Way 4 - Keys are just strings
$contacts = @{
    'full name' = 'C# Code'
    '#' = 1234
}
$contacts['full name'] # OR  $contacts.'full name' OR $key = 'full name' $contacts.$key
<#
    C# Code
#>

## Creating dictionary with values
$contacts = @{
    1 = 'CRM'
    2 = 'C#'
    31 = '.NET'
}
$contacts[4]='Azure'
$contacts[5]='Cloud'

## print contact dictionary
$contacts
<#
    Name                           Value                                                                                                   
    ----                           -----                                                                                                   
    5                              Cloud                                                                                                   
    4                              Azure                                                                                                   
    31                             .NET                                                                                                     
    2                              C#                                                                                                       
    1                              CRM
#>

$contacts_age = @{
    1 = 10
    2 = 20
    3 = 25
}

Tuesday, November 7, 2017

PowerShell – running scripts is disabled on this system.

When i execute powershell script from Windows PowerShell ISE, i got error, means PowerShell execution policy doesn't allow to run script.

Error
File TaskYearApp.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at
http://go.microsoft.com/fwlink/?LinkID=135170.
    + CategoryInfo          : SecurityError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnauthorizedAccess

First i want to see what's my execution policy settings, i run the below commands

PS G:\> get-executionpolicy
Restricted

So PowerShell execution policy is default set to Restricted.

PS G:\> get-executionpolicy -List

  Scope                    ExecutionPolicy
  ---------------       ----------------
  MachinePolicy       Undefined
 UserPolicy              Undefined
 Process                   Undefined
 CurrentUser            Undefined
 LocalMachine         Undefined
 
 List of four different execution policies in PowerShell

  Restricted – No scripts can be run.
  AllSigned – Only scripts signed by a trusted publisher can be run.
  RemoteSigned – Downloaded scripts must be signed by a trusted publisher.
  Unrestricted – All Windows PowerShell scripts can be run.

Workaround solution is, you can change the PowerShell execution policies with Set-ExecutionPolicy cmdlet. Run PowerShell as administrator, Give it the remote signed execution policy which allows to execute that script

PS G:\> powershell -ExecutionPolicy RemoteSigned
- it will take time to set the policy

OR

PS G:\> Set-ExecutionPolicy RemoteSigned 

Thursday, November 2, 2017

MSCRMMonitoringTest Logging 'Monitoring test failed: Test Title: Help Content Server Tests.: Machine: DNSSES1234: ServerRole: HelpServer'

MSCRMMonitoringTest Logging 'Monitoring test failed: Test Title: Help Content Server Tests.: Machine: DNSSES1234: ServerRole: HelpServer'

Every 15 minutes, CRM Logging the below error

Event 18732, MSCRMMonitoringTest

Monitoring test failed: Test Title: Help Content Server Tests.: Machine: <Server_Name>: ServerRole: HelpServer
Test Log:
The remote server returned an error: (404) Not Found.
   at System.Net.HttpWebRequest.GetResponse()
   at Microsoft.Crm.Monitoring.WebHelpers.GetWebResponse(String webpage, Boolean setCrmAuth, Boolean useProxy, Byte[] postData, Boolean setUserAgent, Int64 dmzPort)
   at Microsoft.Crm.Monitoring.Tests.HelpContent.VerifyHelpContent.TestDefaultHelp(TestResult result)
   at Microsoft.Crm.Monitoring.Tests.HelpContent.VerifyHelpContent.Execute()
   at Microsoft.Crm.Monitoring.Engine.MonitoringRuntime.ExecuteMonitoringTest(MonitoringTestBase test, Int32 attempts)

InnerException Type:System.Net.WebException
.

Workaround solution to fix the above logging error

1. Create TestsToExclude.xml file,
<MonitoringTestsToExclude>
    <Test isDisabled="true">VerifyHelpContent</Test>
</MonitoringTestsToExclude>
2. Place it on %ProgramFiles%\Microsoft Dynamics CRM\Monitoring folder (all Servers).

3. After 15 minutes, you see the log with succeded message

All monitoring tests succeeded: Machine: APWMAD0A2398: ServerRole: HelpServer.

MSCRMMonitoringTest Logging 'A certificate registered for use by Microsoft Dynamics CRM has expired'

Every 15 minutes, CRM Logging the below errors

Event 25089, MSCRMMonitoringTest
A certificate registered for use by Microsoft Dynamics CRM has expired.  Certificate type: TrustedIssuer Certificate Name: http://<URL>/adfs/services/trust Expiration Date: 1/11/2016 6:00:00 AM Store Location:  Store Name:

Event 18797, MSCRMMonitoringTest
Monitoring test failed: Test Title: Trusted Issuer Certificate test: Machine: <MACHINE_NAME>: ServerRole: DiscoveryService, Portal, ApiServer
Test Log:
Retrieving certificate data from config DBVerifying TrustedIssuer certificate.  Name=http://<URL>/adfs/services/trustTrustedIssuer certificate is not stored in local store:  It is contained in the config DB.  Name=http://<URL>/adfs/services/trustCertificate Lifespan:  Valid from 09/14/2014 19:00:00 to 01/11/2016 06:00:00Failure: Certificate has expiredVerifying TrustedIssuer certificate.  Name=http://<URL>/adfs/services/trustTrustedIssuer certificate is not stored in local store:  It is contained in the config DB.  Name=http://<URL>/adfs/services/trustCertificate Lifespan:  Valid from 10/12/2015 19:00:00 to 02/15/2017 06:00:00Remaining certificate lifespan 21.7 % is greater than the configured threshold of 10.0 %Certificate is not nearing expiration.

I found 2 expired (invalid) certificates on the servers (Deployment & all UI Servers).

Workaround solution to fix the above logging error

1. Delete older one (yellow color tag) certificate from all servers
A) Run cmd -> type mmc -> Console Root window -> File menu -> select Add/Remove Snap-ins -> Add Cerificate -> Select(Computer account) -> Finish -> OK.

B) Console Root -> Certificates (Local Computer) -> Personal -> Certificates
   -> Select old cerificate (date ended with '02/15/2017' ) -> Delete.

2. Re run ‘Configure Claims-Based Authentication’ tool from CRM Deployment Manager.

3. After 15 minutes, you see the log with succeded message
Monitoring test succeeded: Test Title: Trusted Issuer Certificate test: Machine: <MACHINE_NAME>: ServerRole: DiscoveryService, Portal, ApiServer
Test Log:
Retrieving certificate data from config DBVerifying TrustedIssuer certificate.  Name=http://<URL>/adfs/services/trustTrustedIssuer certificate is not stored in local store:  It is contained in the config DB.  Name=http://<URL>/adfs/services/trustCertificate Lifespan:  Valid from 10/12/2015 19:00:00 to 02/15/2017 06:00:00Remaining certificate lifespan 21.3 % is greater than the configured threshold of 10.0 %Certificate is not nearing expiration.