Configure MSDTC using PowerShell

As of blackpearl v4.6.7, MSDTC is a requirement to deploy workflows.

http://help.k2.com/helppages/k2blackpearlGettingStarted4.6.5/webframe.html?msdtc.html

You can use the following script to automate the MSDTC configuration during VM provisioning.

Note: Execution policy might have to be changed to run this script. (Set-ExecutionPolicy RemoteSigned –Force)

# ———————————
# Enable MSDTC for Network Access
# ———————————
Write-Host “Enabling MSDTC for Network Access…” foregroundcolor yellow
$System_OS=(Get-WmiObject class Win32_OperatingSystem).Caption
If ($System_OS match “2012 R2”)
    {
    Set-DtcNetworkSetting DtcName Local AuthenticationLevel Incoming InboundTransactionsEnabled OutboundTransactionsEnabled RemoteClientAccessEnabled confirm:$false
    }
Else
    {
    .\ConfigureMSDTC.ps1 Out-Null
    }
    Restart-Service MSDTC
Write-Host “——MSDTC has been configured—–” foregroundcolor green

The above script uses the inbuilt cmdlet if your OS is Windows Server 2012 R2, else it will use the traditional approach of modifying the registry.

# Save the following script as a separate file: ConfigureMSDTC.ps1
$DTCSecurity “Incoming”
$RegPath “HKLM:\SOFTWARE\Microsoft\MSDTC\”

#Set Security and MSDTC path
                $RegSecurityPath “$RegPath\Security”
                Set-ItemProperty path $RegSecurityPath name “NetworkDtcAccess” value 1
                Set-ItemProperty path $RegSecurityPath name “NetworkDtcAccessClients” value 1
                Set-ItemProperty path $RegSecurityPath name “NetworkDtcAccessTransactions” value 1
                Set-ItemProperty path $RegSecurityPath name “NetworkDtcAccessInbound” value 1
                Set-ItemProperty path $RegSecurityPath name “NetworkDtcAccessOutbound” value 1
                Set-ItemProperty path $RegSecurityPath name “LuTransactions” value 1             

                if ($DTCSecurity eq “None”)
                {
                    Set-ItemProperty path $RegPath name “TurnOffRpcSecurity” value 1
                    Set-ItemProperty path $RegPath name “AllowOnlySecureRpcCalls” value 0
                    Set-ItemProperty path $RegPath name “FallbackToUnsecureRPCIfNecessary” value 0
                }
                elseif ($DTCSecurity eq “Incoming”)
                {
                    Set-ItemProperty path $RegPath name “TurnOffRpcSecurity” value 0
                    Set-ItemProperty path $RegPath name “AllowOnlySecureRpcCalls” value 0
                    Set-ItemProperty path $RegPath name “FallbackToUnsecureRPCIfNecessary” value 1
                }
                else
                {
                    Set-ItemProperty path $RegPath name “TurnOffRpcSecurity” value 0
                    Set-ItemProperty path $RegPath name “AllowOnlySecureRpcCalls” value 1
                    Set-ItemProperty path $RegPath name “FallbackToUnsecureRPCIfNecessary” value 0
                }

Enable or Disable K2 blackpearl hostserver logging using PowerShell

If you are on a development machine and you need to frequently enable or disable file based host server logging, the following script will come in handy.

Note: Execution policy has to be changed to run this script. (Set-ExecutionPolicy RemoteSigned –Force)

## set-hostserverlogging.ps1 ##

#Set K2HostServer parameters
$k2Host=“localhost”
$k2WorkflowPort=“5252”
[int]$SecondsToWaitForResponse 30
$HostServerLogFile “C:\Program Files (x86)\K2 blackpearl\Host Server\Bin\HostServerLogging.config”
$Status=“”

#Check the current setting
if (Test-Path $HostServerLogFile)
{
$xmldoc (Get-Content $HostServerLogFileas [xml]
$loglevelsetting $xmldoc.SelectSingleNode(‘//LogLocationSettings/LogLocation[@Name=”FileExtension”]/@LogLevel’).‘#text’
}
else
{
write-host(“$HostServerLogFile does not exist”Foregroundcolor Red
Break
}

Function Restart-K2Service
{
[Reflection.Assembly]::LoadWithPartialName(“SourceCode.Workflow.Client”)
Write-Host “Stopping and restarting K2 blackpearl Server Service on ‘$k2Host'” Foregroundcolor Red
Restart-Service displayname “K2 blackpearl Server” EA “Stop”
Write-Host “K2 blackpearl Server Service is restarted successfully” Foregroundcolor Green
Write-Host “Trying to open a connection within $SecondsToWaitForResponse seconds”
$x=0
$success $false
$k2con New-Object SourceCode.Workflow.Client.Connection
while (($x lt $SecondsToWaitForResponseand (!$success))
{
$success $true
$error.clear();
t
rap {write-host “..Failed. will try again” Foregroundcolor Yellow ;continue}
$k2con.Open($k2Host,
“Integrated=True;IsPrimaryLogin=True;Authenticate=True;EncryptedPassword=False;Host=$k2Host;Port=$k2WorkflowPort”);
If($error)
{
$success $false
}
sleep 1;
$x++ 
;
}

If ($Success)
{
$k2con.Dispose()
write-host “K2 service is running and File logging is $Status” Foregroundcolor Green
if ($Status eq “Enabled”)
{
write-host “Check the Host Server\Bin directory for the latest log file”
}
}
else
{
write-host “”
Throw (New-Object System.Management.Automation.RuntimeException “K2 server did not respond in a timely fashion”)
}
}

Function Enable-FileLogging
{
if ($loglevelsetting ne “All”)
{
$xmldoc.SelectSingleNode(‘//LogLocationSettings/LogLocation[@Name=”FileExtension”]/@LogLevel’).‘#text’ ‘All’
$xmldoc.Save((Resolve-Path $HostServerLogFile))
$Status “Enabled”
write-host(“$HostServerLogFile is updated”Foregroundcolor Green
}
else
{
write-host(“File logging is already enabled. No changes are made to the config file”)
Break
}
Restart-K2Service
}

Function Disable-FileLogging
{
if ($loglevelsetting eq “All”)
{
$xmldoc.SelectSingleNode(‘//LogLocationSettings/LogLocation[@Name=”FileExtension”]/@LogLevel’).‘#text’ ‘Error’
$xmldoc.Save((Resolve-Path $HostServerLogFile))
$Status
“Disabled”
write-host(“$HostServerLogFile is updated”Foregroundcolor Green
}
else
{
write-host(“File logging is already disabled. Current setting is $loglevelsetting. No changes are made to the config file”)
Break
}
Restart-K2Service
}

Function Select-Item
{
Param([String[]]$choiceList[String]$Caption=“Please make a selection”[String]$Message=“Choices are presented below”[int]$default=)
$choicedesc 
New-Object System.Collections.ObjectModel.Collection[System.Management.Automation.Host.ChoiceDescription]
$choiceList foreach $choicedesc.Add((New-Object “System.Management.Automation.Host.ChoiceDescription” ArgumentList $_))}
$Host.ui.PromptForChoice($caption$message$choicedesc$default)
}

#Present the choice to the user
Switch (select-item Caption “Set HostServer Logging” Message “Do you want to: ” choice “&Enable”,“&Disable”,“&Cancel” default 0)
{
{ Enable-FileLogging }
{ Disable-FileLogging }
}


Exchange Management Service Broker troubleshooting in K2 blackpearl

Points to take note:

  • The following screenshots are taken on K2 Core 4.1 VM with blackpearl 4.5 Update KB001420.
  • Exchange2010 and Blackpearl are installed on the same machine.
  • The logged in user is denallix\administrator.
  • Pre-requisites: http://help.k2.com/kb001189.aspx
  • KB001189 quotes you need a second service account. This is not compulsory and I have used K2 service account to do all the operations. So only one account is sufficient.
  • All the errors start with “Please make sure the K2 service account has impersonation rights in Exchange” This is a misleading message, so ignore that bit and look for the text after that.

=========================================================================================

Option 1: Set Authentication Mode to ServiceAccount [DENALLIX\K2Service]

“DENALLIX\K2Service” is member of following AD roles:

With the settings in place, we can create a meeting “On Behalf Of” any user as shown in the next 3 screenshots

Error: The SMTP address has no mailbox associated with it.
Cause: This happens if the “On Behalf Of” field has an invalid email address or the email is not found in Exchange

Error: The SMTP address format is invalid.
Cause: This happens if the “On Behalf Of” field does not have a value in the format of a valid email address

=========================================================================================

Option 2: Set Authentication Mode to Impersonate [Enforce Impersonation is unchecked]

The following Exchange Management Shell screenshot shows “DENALLIX\K2Service” is part of Exchange’s ApplicationImpersonation role. This was done during installation by the K2 setup manager.

Get-ManagementRoleAssignment Role “ApplicationImpersonation”

If you want to know more about Role Based Access Control (RBAC), please check this: http://www.msexchange.org/articles_tutorials/exchange-server-2010/management-administration/exchange-2010-role-based-access-control-part1.html

With the above settings in place, we can create a meeting “On Behalf Of” any user as shown in the next 2 screenshots. The smartobject tester tool is running under the context of logged in user denallix\administrator

=========================================================================================

Option 3: Set Authentication Mode to Impersonate and check “Enforce Impersonation”

Since the logged in user is denallix\administrator, the Smartobject tester tool ran using those credentials:

Error: The account does not have permission to impersonate the requested user.
Cause: ‘denallix\administrator’ account is not part of Exchange’s ApplicationImpersonation role

Resolution:
new-ManagementRoleAssignment Name “_suImpersonateRoleAsg” Role “ApplicationImpersonation” User “administrator@denallix.com”

Note: After executing the new-ManagementRoleAssignment powershell cmdlet, you must wait 5-10 minutes (depends on exchange setup) for the smartobject to pick up those changes.

After waiting for the exchange role refresh, you should be able to create the meeting with Enforce Impersonation enabled.

=========================================================================================

Option 4: ‘Run as different user’ option to launch Smartobject tester tool, Set Authentication Mode to Impersonate and check “Enforce Impersonation”

The error is same as explained previously. But if you try to execute the new-ManagementRoleAssignment powershell cmdlet, you will get an error as below:

This is due to the usage of same name “_suImpersonateRoleAsg” in the command. So delete the existing entry and then add the user to the role.

Remove-ManagementRoleAssignment “_suImpersonateRoleAsg”

The above screenshot confirms that _suImpersonateRoleAsg role will be removed which has Administrator as the member. Since the role has now been deleted, you can add “Run as” user to the exchange role.

As mentioned earlier, you must wait 5-10 minutes before trying to create the meeting request.