Microsoft Dynamics NAV 2015 Server Instance Tenants Discovery

Microsoft.Dynamics.Nav.2015.TenantDiscovery (Discovery)

This object discovery finds all tenants that are mounted on Microsoft Dynamics NAV 2015 Server instances.

Knowledge Base article:

Summary

This object discovery finds all tenants on Microsoft Dynamics NAV 2015 Server instances.

Element properties:

TargetMicrosoft.Dynamics.Nav.2015.ServerInstance
EnabledTrue
Frequency14400
RemotableFalse

Object Discovery Details:

Discovered Classes and their attribuets:

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Dynamics.Nav.2015.TimedPowerShell.DiscoveryProvider Microsoft.Dynamics.Nav.2015.DefaultAccount

Source Code:

<Discovery ID="Microsoft.Dynamics.Nav.2015.TenantDiscovery" Target="Microsoft.Dynamics.Nav.2015.ServerInstance" Enabled="true" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="Microsoft.Dynamics.Nav.2015.Tenant"/>
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Microsoft.Dynamics.Nav.2015.TimedPowerShell.DiscoveryProvider" RunAs="Microsoft.Dynamics.Nav.2015.DefaultAccount">
<IntervalSeconds>14400</IntervalSeconds>
<TimeoutSeconds>120</TimeoutSeconds>
<ScriptName>TenantDiscoveryScript.ps1</ScriptName>
<Arguments>'$Target/Id$' '$MPElement$' '$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$' '$Target/Property[Type="Microsoft.Dynamics.Nav.2015.ServerInstance"]/ServerInstance$' '$Target/Property[Type="Service!Microsoft.SystemCenter.NTService"]/ServiceName$'</Arguments>
<ScriptBody><Script>
# ServerInstanceDiscoveryScript.ps1
# Copyright (c) Microsoft Corporation. All rights reserved.
$scriptName = 'NavAdminTool.ps1'

$errorVariable = $null
$instanceName = ''
$arguments = ''
for ($i = 0; $i -lt $args.Count; $i++)
{
$arguments += " '$($args[$i])'"
}

# Generates a well formatted error details message, that helps troubleshooting
function Generate-ErrorDetails([string] $functionName)
{
[string] $errorRecord = [string]::Format("{0}`n{1}`n{2}`n{3}`n",$Error[0].Exception.Message,$Error[0].InvocationInfo.Line,$Error[0].InvocationInfo.PositionMessage,$Error[0].Exception)
if($Error[0].Exception.InnerException -ne $null) { $errorRecord = $errorRecord + $Error[0].Exception.InnerException }
$errorRecord = "`nScript: " + $scriptName + "`nArguments: " + $arguments + "`nInstanceName: " + $instanceName + "`nFunctionName: " + $functionName + "`n`nError: " + $errorRecord
$Error[0].ErrorDetails = $errorRecord
}

# writes the last error record to the OperationManager eventlog
function Log-ScriptError()
{
# LogScriptEvent see http://msdn.microsoft.com/en-us/library/bb437630.aspx
[int] $severity = 1
[int] $eventId = 2015
[string] $eventSourceName = 'Microsoft Dynamics NAV 2015 Management Pack'

$scomapi.LogScriptEvent($eventSourceName, $eventId, $severity, $Error[0].ErrorDetails)
}

# Import-Module or register Snap-in, that will enable side-by-side registrations of management dll
function RegisterSnapIn($snapIn)
{
$nstPath = "HKLM:\SOFTWARE\Microsoft\Microsoft Dynamics NAV\80\Service"
$managementDllPath = Join-Path (Get-ItemProperty -path $nstPath).Path '\Microsoft.Dynamics.Nav.Management.dll'

# First try to import the management module
Import-Module $managementDllPath -ErrorVariable errorVariable -ErrorAction SilentlyContinue

if (Check-ErrorVariable -eq $true)
{
# fallback to add the snap-in
if ((Get-PSSnapin -Name $snapIn -ErrorAction SilentlyContinue) -eq $null)
{
if ((Get-PSSnapin -Registered $snapIn) -eq $null)
{
throw "Could not locate the PSSnapin: $snapIn"
}
else
{
Add-PSSnapin $snapIn
}
}
}
}

# Check if there is any error in the ErrorVariable
function Check-ErrorVariable
{
return ($errorVariable -ne $null -and $errorVariable.Count -gt 0)
}

# TenantDiscoveryScript.ps1
# Copyright (c) Microsoft Corporation. All rights reserved.
$scriptName = 'TenantDiscoveryScript.ps1'

# Assign global variables to parameters passed in from the command line.
$target = $args[0]
$element = $args[1]
$principalName = $args[2]
$serverInstance = $args[3]
$serviceName = $args[4]

# main()
try
{
$scomapi = new-object -comObject "MOM.ScriptAPI"

# Register Microsoft Dynamics NAV Management Snap-in
RegisterSnapIn "Microsoft.Dynamics.Nav.Management"

# Create the discovery data structure that we will return the discovered objects in
$discData = $scomapi.CreateDiscoveryData(0, $element, $target)

# Get a list of all tenants, for a given server instance
$foundTenants = Get-NavTenant $serverInstance

# Create SCOM objects for the NAV Tenants
foreach ($tenant in $foundTenants)
{
$instanceName = $tenant.Id
# Create the Tenants object and initialize it with its key properties, no matter what.
$navTenant = $discData.CreateClassInstance("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']$")
$navTenant.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $principalName)
$navTenant.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $tenant.Id)
$navTenant.AddProperty("$MPElement[Name='Service!Microsoft.SystemCenter.NTService']/ServiceName$", $serviceName)

# Reading the NAVTenant properties
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/TenantId$", $tenant.Id)
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/ServerInstance$", $serverInstance)
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/DatabaseServerAndInstance$", $tenant.DatabaseServer)
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/DatabaseName$", $tenant.DatabaseName)
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/AlternateTenantIds$", [String]::Join(", ", $tenant.AlternateId))
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/AllowApplicationDatabaseWrites$", $tenant.AllowAppDatabaseWrite)
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/NASServicesEnabled$", $tenant.NASServicesEnabled)
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/DefaultCompany$", $tenant.DefaultCompany)
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/DefaultTimeZone$", $tenant.DefaultTimeZone.DisplayName)
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/TenantState$", $tenant.State.ToString())
$navTenant.AddProperty("$MPElement[Name='Microsoft.Dynamics.Nav.2015.Tenant']/DetailedState$", $tenant.DetailedState.ToString())

# add the WebServerInstance to the DiscoveryData object
$discData.AddInstance($navTenant)
}

$scomapi.Return($discData)
}
catch
{
Generate-ErrorDetails "main"
Log-ScriptError
Exit -1
}
</Script></ScriptBody>
</DataSource>
</Discovery>