Skip to main content

Notifications

Microsoft Dynamics NAV (Archived)

How to Balance NAV "Windows Clients" / Dynamics NAV Server

Posted on by Microsoft Employee

Hi together,

 

are you looking for a clever balancing between your Microsoft Dynamics NAV Server’s (NST)?

 I'm searching for a long time and find no standard way in NAV (NAV2013, NAV2015, NAV2016, NAV2017 or NAV2018). 

 

For sure you know that you can add some parameter to RTC to make sure the NAV users are on the right database

 

Something like that:

 

"C:\Program Files (x86)\Microsoft Dynamics NAV\100\RoleTailored Client\Microsoft.Dynamics.Nav.Client.exe" -"settings:\\SERVERXY\Config\SettingsNAV2017.config "

 

With that in mind we are very close to the Solution:

 

1346.1.png

 

All 3 Microsoft Dynamics NAV Service Tiers (NST’s) are connected to database NAV2017.

 

4061.2.png

 

 

Windows Task scheduler start‘s every 5 or 10min our Powershell Skipt.

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"

-command "C:\scripts\NavBalancer.ps1" -noninteractive

 

  

At „C:\NAV\Config“ on our NST Windows Server "SERVERXY"  is our standard „RTC Config file“ “SettingsNAV2017.config” for all clients in the company.

 4061.4.png

I our example it’ also a shared folder (\\SERVERXY\Config).

 

For our 3 NSTs, we need also 3 different „RTC Config file“.

NST1 have a „RTC Config file“ that belongs to NST1 “NAV2017_1” – Port 7046

NST2 have a „RTC Config file“ that belongs to NST2 “NAV2017_2” – Port 8046

NST3 have a „RTC Config file“ that belongs to NST3 “NAV2017_3” – Port 9046

 3312.5.png

Powershell:

 

So, what’s in that magic script you are looking for:

No magic, just a simple NST counter check

 

PS1

 

1. Definition ot the counters:

  • Definition of the counter that you want to check at each NSt (with Powershell) before you choose the right NST.
  • Minimum users at a NST should be round about 10. After you reach 10, the next NST is in our example the best one.
  • You can also choose 50 or more. Or combine it with MS NLB.
  • Number of the NSTs that I want to use for the balancing. In our example 3.

 

2. Process to check what’s up at the NST

  • We call with PowerShell the standard MS counter of the “Microsoft Dynamics NAV” Server. NAV2017_1; NAV2017_2; NAV2017_3.
  • We don’t switch wild between the NSt’s We allwas checkk the “Activs Session“. It’s the same like Page9506.
  • In Perfom or Powershell we have to search for this counter „# Active sessions“
  • That give us a live view into the current user load. And some of you know, there are more counters. Maybe later

 

3. Copy process to give the useres the prefert „RTC Config file“ at the shared Folder

  • \\SERVERXY\config\“  is the default "SettingsNAV2017.config" folder that all RTC users are using.

  • "C:\Program Files (x86)\Microsoft Dynamics NAV\100\RoleTailored Client\Microsoft.Dynamics.Nav.Client.exe" -"settings:\\SERVERXY\Config\SettingsNAV2017.config”

 

#  Script name:   NavBalancer.ps1

#  Created on:    12.10.2017

#  Updated on:    01.12.2017

#  Author:        T.B. & S.K.

#  Purpose:       Check currently usage of NST and change config files if usage has reached minimum tier usage

#  posible counters are:

 

### common config file name ###

$configFileName = "SettingsNAV2017.config"

### path of currently used configuration ###

$activeConfigPath = "\\SERVERXY\Config\" + $configFileName

### base path for tiering config files: add tiernumber to acces specific config file ###

$configPath = "C:\NAV\BalanceNSTConfig\NST"

### base name of performance counter

$counterBaseName = "nav2017_"

 

### number of tier for this server: !!! tier numbers start at 1 !!! ###

$numberOfTiers = 3

### set minimum users per tier ###

$minimumUsersPerTier = 10

### active tier: default 0 ###

$activeTier = 0

### vars for less used tier ###

$lessUsedTier = 0

[int]$lessUsedTierCounter = 0

 

### get currently used tier from active config file ###

[xml]$activeConfigFile = Get-Content $activeConfigPath

$currentTier = ($activeConfigFile.configuration.appSettings.add | Where-Object {$_.key -eq "ServerInstance" }).value.split("_")[-1]

 

### check current usage of each service tier ###

for($i=1; $i -le $numberOfTiers; $i++) {

   $counterName = $counterBaseName + $i

   if (get-counter -counter "\Microsoft Dynamics NAV($counterName)\# Active sessions") {

       [int]$counterVal = (get-counter -counter "\Microsoft Dynamics NAV($counterName)\# Active sessions").countersamples.cookedvalue

       # set vars for less used tier on first run

       if ($lessUsedTier -eq 0) {

           $lessUsedTier = 1

           $lessUsedTierCounter = $counterVal

       } else {

           # if new less tier was detected update vars

           [boolean]$setNewLessCounterVars = $counterVal -lt $lessUsedTierCounter

           if ($setNewLessCounterVars) {

               $lessUsedTier = $i

               $lessUsedTierCounter = $counterVal

           }

       }

      

       if($counterVal -lt $minimumUsersPerTier) {

           if($activeTier -eq 0) {

               $activeTier = $i

           }

       }

   }

}

### set active tier to less used if all tiers have more than minimum users

if ($activeTier -eq 0) {

   $activeTier = $lessUsedTier

}

 

#[Console]::WriteLine("CurrentTier: " + $currentTier + " -- NewActiveTier: " + $activeTier)

### copy config file if active is not currently used tier ###

if($currentTier -ne $activeTier) {

   ### define source item path and copy to active config path ###

   $configFilePath = $configPath + $activeTier + "\" + $configFileName

   #[Console]::WriteLine("Copy: " + $configFilePath + " to: " + $activeConfigPath)

   Copy-Item -Path $configFilePath -Destination $activeConfigPath

}

 #Updated TB Code

 

### global info ###

 

### display all counters for microsoft dynamics nav ###

#(get-counter -listset "microsoft dynamics nav").counter

 

### get counter values for all instances ###

#get-counter -counter "\Microsoft Dynamics NAV(*)\# Active sessions"

 

### get counter value object for "nav2017" instance ###

#(get-counter -counter "\Microsoft Dynamics NAV(nav2017)\# Active sessions")

 

### get numeric counter value for "nav2017" instance ###

#(get-counter -counter "\Microsoft Dynamics NAV(nav2017)\# Active sessions").countersamples.cookedvalue

 #===============================================================================================

 

#maybe you want to expand the check:-)

#ALL COUNTERS:

#"% Primary key cache hit rate"
#"# Primary key cache total requests"
#"% Command cache hit rate"
#"# Command cache total requests"
#"% Preferred connection cache hit rate"
#"# Preferred connection total requests"
#"# Open connections"
#"% Query repositioning rate"
#"% Result set cache hit rate"
#"# Result set cache total requests"
#"% Calculated fields cache hit rate"
#"# Calculated fields cache total requests"
#"Heartbeat time (ms)"
#"# Rows in all temporary tables"
#"Soft throttled connections"
#"Hard throttled connections"
#"Transient errors"
#"# Mounted tenants"
#"Server operations/sec"
#"# Active sessions"
#"Average server operation time (ms)"
#"Total # Pending tasks"
#"Total # Running tasks"
#"# Running tasks"
#"# Available tasks"
#"Maximum # of tasks"
#"# of task errors/sec"
#"Average task execution time"
#"Time (ms) since the list of running tasks last had capacity for new tasks"
#"# Open tenant connections"
#"# Open application Connections"

*This post is locked for comments

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: How to Balance NAV "Windows Clients" / Dynamics NAV Server

    Hi, I know BC is comming but so long wie can call NST service counter and use the Windows Client we can change the config settings:-)

    Attached my current script for 2 Windows Servers 2016 with 6 NSTs(3 on SERVERXY1 and 3 on SERVERXY2).

    <#

    .SYNOPSIS

    Load-Balancing NAV services

    .DESCRIPTION

    Check User at NST services

    .NOTES

    Author: S. K.

    Version: 2.0

    Creation Date 01.12.2017

    Change log. 01.01.2018

    Check usage of NST and change config files if usage has reached minimum tier usage for 2 Windows Server and 6 NST(3 on SERVERXY1 and 3 on SERVERXY2)

    .EXAMPLE

    Example of how to use this cmdlet, function or script

    .EXAMPLE [optional]

    Another example of how to use this cmdlet, function or script

    .INPUTS [optional]

    Inputs to this cmdlet, function or script

    .OUTPUTS

    Output from this cmdlet, function or script

    .LINK

    Enter URL to system master file or CMDB documentation as well as scripts or applications this script depends on

    #>

     

    $MinimumUser = 3

    $NavServiceName = 'srv'

    $NavServers = 'SERVERXY1','SERVERXY2'

    $LastCharOfService = 0

    $ActiveConfigPath = "\\Common\NAV\DEV\RTC_DE.config"

     

    $ServerArray = [System.Collections.ArrayList]::new()

    Foreach($NavServer in $NavServers)

    {

    $ServerobjHash =@{ Name = $NavServer

    Status = $false

    Services = ([System.Collections.ArrayList]::new())

    }

    $NavServer = New-Object -TypeName psobject -Property $ServerobjHash

    $CheckResult = Test-NetConnection -ComputerName $NavServer.name

    if($CheckResult.PingSucceeded)

    {

    $NavServer.Status = $true

    }

    $null = $ServerArray.Add($NavServer)

    }

    Foreach($NavServer in $ServerArray)

    {

    #Sevice Check

    $ServicesOnServer = Get-Service -ComputerName $NavServer.Name | Where-Object{$_.Name -match "MicrosoftDynamicsNavServer" -and $_.Name -match "$NavServiceName" -and $_.Status -like "RUNNING"}

    #$ServicesOnServer = Get-Service -ComputerName $NavServer.Name | Where-Object{$_.Name -match "MicrosoftDynamicsNavServer`$$NavServiceName" -and $_.Status -like "RUNNING"}

    foreach($ServiceOnServer in $ServicesOnServer)

    {

    #get-counter -computername SERVERXY1 -counter "\Microsoft Dynamics NAV(*)\# Active sessions"

    $lastCharOfService = $ServiceOnServer.Name.Substring($ServiceOnServer.Name.Length - 1)

    #$lastCharOfService = "1"

    $URLString = ("\Microsoft Dynamics Nav(srv" + $lastCharOfService + ')\# Active sessions')

    #$URLString = ('\\'+ $NavServer.Name +'\' + "MicrosoftDynamicsNavServer(srv" + $lastCharOfService + ')\# Active sessions')

    #get-counter -computername $NavServers -counter $URLString

    #get-counter -computername $NavServers -counter "\Microsoft Dynamics NAV(srv1)\# Active sessions"

    #All Counter

    #cls

    #Get-Counter "\*\*

    ###

    $ServiceobjHash =@{ Name = $ServiceOnServer.Name

    Status = $ServiceOnServer.Status

    Sessions = get-counter -computername $NavServer.Name -counter ("\Microsoft Dynamics NAV(srv" + $lastCharOfService + ')\# Active sessions')

    #Sessions = get-counter -computername $NavServer.Name -counter ('\\'+ $NavServer.Name +'\' + "MicrosoftDynamicsNavServer(srv" + $lastCharOfService + ')\# Active sessions')

    }

    #$ServiceobjHash.Values

    $Service = New-Object -TypeName psobject -Property $ServiceobjHash

    $null = $NavServer.Services.add($Service)

    }

    }

    $TempSessions = 100

    $ind = $true

    foreach ($Server in $ServerArray)

    {

    Foreach ($Service in $Server.Services)

    {

    #MinimumUser

    if(($Service.sessions.CounterSamples.cookedvalue -lt $MinimumUser) -and $ind)

    {

    $ind = $false

    write-host "Keine sessions" $Server.Name $Service.Name $Service.sessions.CounterSamples.cookedvalue -BackgroundColor red

    $actionhash = @{

    ServerName = $Server.Name

    ServiceName = $Service.Name

    ActiveSessions = $Service.sessions.CounterSamples.cookedvalue

    }

    $ActionObject = New-Object -TypeName psobject -Property $actionhash

    }

    else

    {

    if(($TempSessions -gt $Service.sessions.CounterSamples.cookedvalue) -and $ind)

    {

    $TempSessions = $Service.sessions.CounterSamples.cookedvalue

    write-host "Sessions" $Server.Name $Service.Name $Service.sessions.CounterSamples.cookedvalue -ForegroundColor Green

    $actionhash = @{

    ServerName = $Server.Name

    ServiceName = $Service.Name

    ActiveSessions = $Service.sessions.CounterSamples.cookedvalue

    }

    $ActionObject = New-Object -TypeName psobject -Property $actionhash

    }

    }

    }

    }

    If($actionhash -eq $null)

    {

    #$actionhash

    #Name Value

    #ServerName SERVERXY1

    #ServiceName MicrosoftDynamicsNavServer$SRV1

    write-host "If actionhash -eq null, than copy config folder - "+$ActionObject.ServerName -BackgroundColor blue

    $LastCharOfService = $actionhash.ServiceName.Substring($actionhash.ServiceName.Length - 1)

    #$ConfigFilePath = "\\sm.local\public\Common\NAV\DEV\SERVERXY1\SRV1\RTC_DE.config"

    $ConfigFilePath = "\\Common\NAV\DEV\" + $ActionObject.ServerName + "\" + $NavServiceName + $LastCharOfService +"\RTC_DE.config"

    Copy-Item -Path $ConfigFilePath -Destination $ActiveConfigPath

    }

     

    If($actionhash -ne $null)

    {

    Copy-Item -Path $ConfigFilePath -Destination $ActiveConfigPath

    }

    regards

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: How to Balance NAV "Windows Clients" / Dynamics NAV Server

    Hi,

    is it working?

    thanks?

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: How to Balance NAV "Windows Clients" / Dynamics NAV Server

    Great solution, and thanks for sharing it!

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Community AMA December 12th

Join us as we continue to demystify the Dynamics 365 Contact Center

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,240 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,149 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans