Common Discovery Data source module (Shell out version).

Microsoft.LS.2019.Discovery.Common.DS.ShellOut (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsMicrosoft.LS.2019.RunAs.Account.Discovery
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource System.CommandExecuterDiscoveryDataSource Default

Source Code:

<DataSourceModuleType ID="Microsoft.LS.2019.Discovery.Common.DS.ShellOut" Accessibility="Internal" RunAs="Microsoft.LS.2019.RunAs.Account.Discovery" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SyncTime" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ScriptName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ScriptFileName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ScriptBody" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="EventId" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TargetComputer" type="xsd:string"/>
</Configuration>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="System!System.CommandExecuterDiscoveryDataSource">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<ApplicationName> %windir%\system32\windowspowershell\v1.0\powershell.exe</ApplicationName>
<WorkingDirectory/>
<CommandLine>-Command ".\$Config/ScriptFileName$"</CommandLine>
<SecureInput/>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>$Config/ScriptFileName$</Name>
<Contents><Script>
$SourceId = '$MPElement$'
$ManagedEntityId = '$Target/Id$'
$TargetComputer = '$Config/TargetComputer$'
#############################################################################
# 1. Initialize MOM api.
# 2. Import Skype for Business Server 2019 Powershell module.
# 3. Check for parameters.
# 4. Execute Script Body.
# 5. Return Discovery Data.
# 6. Log Events for Traces.
#############################################################################

#CONSTANTS###################################################################
$LOG_REG_KEY = "HKLM:\Software\Microsoft\Real-Time Communications\Health"
$EVENT_ERROR = 1
$EVENT_WARNING = 2
$EVENT_INFORMATION = 4
$EVENT_ID = $Config/EventId$
$EVENT_SCRIPT_NAME = "$Config/ScriptFileName$"
#############################################################################

#LOGS &amp; EXCEPTIONS###########################################################
$PROPERTY_VALUE = "Value of {0} is {1}."
$NO_NULL = "Error: {0} can not be null."
$DISCOVERY_SUCCESS = "{0} discovery completed for {1}."
$DISCOVERY_EXCEPTION_MESSAGE = "An exception occurred during discovery script, Exception : {0}."
$MESSAGE_LENGTH_HIT_LIMIT = "MESSAGE TRUNCATED DUE TO SIZE LIMIT. Max Limit is [{0}]."

#############################################################################

#Helper Functions############################################################
function ParseException($exception)
{
$exceptionString = ""
$exceptionString += $exception.Exception.ToString() + "`n"
if ($exception.InvocationInfo -ne $null)
{
$exceptionString += $exception.InvocationInfo.PositionMessage + "`n"
}
$exceptionString

}
$Script:logMessage = new-object System.Text.StringBuilder
function TRACE ($message)
{
$Script:logMessage.Append($message) | out-null
$Script:logMessage.Append("`n") | out-null
}

function GetDiscoveryData()
{
$Script:SCOMDiscoveryData
}

# Unfortunately, foreach loop is iterating over $null values. Thank you, Powershell!!!
# In other words;
# foreach {$x in $null} {"test"} =&gt; Is printing "test" one time.
# to prevent this we need to use below format.
# foreach (... in strip-null (..)) {}
# E.g foreach {$x in strip-null($null)} {"test"} =&gt; Does not print "test".
# http://www.techtalkz.com/microsoft-windows-powershell/165444-foreach-null-interates-block.html
function strip-null($obj)
{
if ($obj -ne $null) { $obj }
}
#############################################################################

#SCRIPT INFO#################################################################
$currentUser = whoami
# Check the execution policy of scripts and see if it is what is expected for our scripts to run if not
# set it to RemoteSigned which is the least supported execution policy this is a fix for RTMA-1762.
$supportedExecutionPolicies="RemoteSigned","Unrestricted","Bypass"
$executionPolicy = get-executionpolicy
if(!($supportedExecutionPolicies -contains $executionPolicy))
{
set-executionpolicy RemoteSigned
$executionPolicy = get-executionpolicy
}

TRACE ("`n")
TRACE ("--------------------------------------------------------------------------------")
TRACE ("-Script Name: {0}" -f "$Config/ScriptName$")
TRACE ("-Run as account: {0}" -f $currentUser)
TRACE ("-Execution Policy: {0}" -f $executionPolicy)
TRACE ("--------------------------------------------------------------------------------")

#############################################################################
$Script:MOMapi = New-Object -comObject "MOM.ScriptApi"
try
{
# Terminate Execution in Error Conditions.
$ErrorActionPreference = "Stop"

if(!$SourceId) { throw $NO_NULL -f "Source Id" }
TRACE ($PROPERTY_VALUE -f "Source Id", $SourceId)

if(!$ManagedEntityId) { throw $NO_NULL -f "ManagedEntity Id" }
TRACE ($PROPERTY_VALUE -f "ManagedEntity Id", $ManagedEntityId)

if(!$TargetComputer) { throw $NO_NULL -f "Target Computer" }
TRACE ($PROPERTY_VALUE -f "Target Computer", $TargetComputer)

$Script:SCOMDiscoveryData = $MOMapi.CreateDiscoveryData(0, $SourceId, $ManagedEntityId)

$Config/ScriptBody$

$MOMApi.Return($Script:SCOMDiscoveryData)
}
catch
{
TRACE ($DISCOVERY_EXCEPTION_MESSAGE -f (ParseException $_))
$exceptionOccured = $true;
if ($Script:SCOMDiscoveryData)
{
# Unset IsSnapHost flag. Should not delete perivious discoveries, if not able to complete intialization phase.
$Script:SCOMDiscoveryData.IsSnapshot = $false
$MOMApi.Return($Script:SCOMDiscoveryData)
}
}

TRACE ("--------------------------------------------------------------------------------")

if($exceptionOccured)
{
$EVENT_SEVERITY = $EVENT_ERROR
}
else
{
$EVENT_SEVERITY = $EVENT_INFORMATION
}

# We need to safeguard ourself against the message limit. The documented message limit is 32786 bytes (~32K).
# http://msdn.microsoft.com/en-us/library/aa363679(VS.85).aspx
# however, when we use mom api to log event it adds some characters to the messages.
# Thus, we restrict the message limit here to 30720(30K).
# if the message is greater than this, we simply truncate it and update the log message.
$maxLimit = 30720
if($logMessage.Length -gt $maxLimit)
{
TRACE ($MESSAGE_LENGTH_HIT_LIMIT -f $maxLimit)
$MOMapi.LogScriptEvent($EVENT_SCRIPT_NAME, $EVENT_ID, $EVENT_SEVERITY , $logMessage.ToString().Substring(0, $maxLimit))
}
else
{
$MOMapi.LogScriptEvent($EVENT_SCRIPT_NAME, $EVENT_ID, $EVENT_SEVERITY , $logMessage.ToString())
}
</Script></Contents>
</File>
</Files>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>