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:
All 3 Microsoft Dynamics NAV Service Tiers (NST’s) are connected to database NAV2017.
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.
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
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:
2. Process to check what’s up at the NST
3. Copy process to give the useres the prefert „RTC Config file“ at the shared Folder
# 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
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
Hi,
is it working?
thanks?
Great solution, and thanks for sharing it!
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 291,240 Super User 2024 Season 2
Martin Dráb 230,149 Most Valuable Professional
nmaenpaa 101,156