#---------------------------------------------------------------------------
# Returns WMI Instance requested. Tries to execute WMI query a N times.
#---------------------------------------------------------------------------
Function WMIGetInstanceExTryN
{
param ([string]$sTargetComputer,
[string]$sNamespace,
[string]$sInstanceQuery,
[int]$N)
for ($i = 0; $i -lt $N; $i++)
{
$error.Clear();
$oInstance = Get-CimInstance -ComputerName $sTargetComputer -Namespace $sNamespace -Query ("Select * from "+$sInstanceQuery) -ErrorAction SilentlyContinue
if ($error.Count -gt 0)
{
if ($i -eq ($N-1))
{
ThrowScriptError ("The class name '" + $sInstanceQuery + "' returned no instances. Please check to see if this is a valid WMI class name.") $error[0]
}
}
else
{
break;
}
sleep -m 1000
}
$error.Clear();
$oInstance = Get-CimInstance -ComputerName $sTargetComputer -Namespace $sNamespace -Query ("Select * from "+$sInstanceQuery) -ErrorAction SilentlyContinue
if ($error.Count -gt 0)
{
ThrowScriptError ("The class name '" + $sInstanceQuery + "' returned no instances. Please check to see if this is a valid WMI class name.") $error[0]
}
return $oInstance
}
#---------------------------------------------------------------------------
# Connect to WMI.
#---------------------------------------------------------------------------
Function WMIConnect
{
param ([string]$sTargetComputer,
[string]$sNamespace)
$error.Clear()
# !!! Refactoring comment:
# Original VBScript only tries to connect to the namespace. Piping to get only the first one saves time.
$oWMI = Get-CimClass -ComputerName $sTargetComputer -Namespace $sNamespace -ErrorAction SilentlyContinue | select -First 1
if ($error.Count -gt 0)
{
$msg = "Unable to open WMI Namespace 'winmgmts:\\" + $sTargetComputer + "\" + $sNamespace + "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists."
ThrowScriptError $msg $error[0]
}
}
#---------------------------------------------------------------------------
# Executes the WMI query and returns the result set.
#---------------------------------------------------------------------------
Function WMIExecQuery
{
param ([string]$sTargetComputer,
[string]$sNamespace,
[string]$sQuery)
$error.Clear()
# !!! Refactoring comment:
# Original VBScript only tries to connect to the namespace. Piping to get only the first one saves time.
$oWMI = Get-CimClass -ComputerName $sTargetComputer -Namespace $sNamespace -ErrorAction SilentlyContinue | select -First 1
if ($error.Count -gt 0)
{
$msg = "Unable to open WMI Namespace 'winmgmts:\\" + $sTargetComputer + "\" + $sNamespace + "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists."
ThrowScriptError $msg, $error[0]
}
$oQuery = Get-CimInstance -ComputerName $sTargetComputer -Namespace $sNamespace -Query $sQuery -ErrorAction SilentlyContinue
if ($error.Count -gt 0)
{
ThrowScriptError ("The Query '" + $sQuery + "' returned an invalid result set. Please check to see if this is a valid WMI Query.") $error[0]
}
return $oQuery
}
#---------------------------------------------------------------------------
# Executes the WMI query and returns the result set, no abort version.
#---------------------------------------------------------------------------
Function WMIExecQueryNoAbort
{
param ([string]$sTargetComputer,
[string]$sNamespace,
[string]$sQuery)
#---------------------------------------------------------------------------
# Creates an event and sends it back to the mom server.
#---------------------------------------------------------------------------
Function ThrowScriptErrorNoAbort
{
param ([string]$sMessage,
[System.Management.Automation.ErrorRecord]$oErr)
# Retrieve the name of this (running) script
$ScriptFileName = $MyInvocation.ScriptName
#---------------------------------------------------------------------------
# Creates an event and sends it back to the mom server.
#---------------------------------------------------------------------------
Function ThrowScriptError
{
param ([string]$sMessage,
[System.Management.Automation.ErrorRecord]$oErr)
ThrowScriptErrorNoAbort $sMessage $oErr
exit
}
#---------------------------------------------------------------------------
# Outputs to file and echo for debugging purposes
#---------------------------------------------------------------------------
Function TraceLogMessage
{
param ([string]$sMessage)
Write-Host $sMessage
If ($g_DebugFlag -eq $true)
{
# Retrieve the name of this (running) script
$ScriptFileName = $MyInvocation.ScriptName
#---------------------------------------------------------------------------
# Verifies the expression. If equals to False then generates an error and quits the script
# Usage:
# Verify Not WMISet Is Nothing, "WMISet is invalid!"
# Verify WMISet.Count = 1, "Invalid quantity of services with name 'Server' (qty = " & WMISet.Count & ")."
#---------------------------------------------------------------------------
Function Verify
{
param ([bool]$bBool,
[string]$sMessage)
If ($bBool -eq $false)
{
ThrowScriptError $sMessage $null
}
}
Function GetRegistryKeyValue
{
param ([string]$keyPath,
[string]$key)
#Copyright (c) Microsoft Corporation. All rights reserved.
# Parameters that should be passed to this script
# 0 MPElement ID ($MPElement$)
# 1 Target Id for ME this rule is running against ($Target/Id$)
# 2 Computer (FQDN) that the Network Adapter will be hosted on
# 3 Computer ID (Key) that the Network Adapter will be hosted on
# 4 Should we discover disabled Network Adapters or not
# 5 Use MacAddress for discovery (true), otherwise NetConnectionID
$WIN_SRV_VNEXT_OSVer = "6.3"
Function Main()
{
$oDiscoveryData = $momAPI.CreateDiscoveryData(0, $SourceID, $ManagedEntityId)
Function DoDiscovery
{
param ([string]$sTargetComputer, [string]$sTargetComputerID, $oDisc, $IsDiscoverDisabled, $IsUseMacAddress)
$boolUseWINVNEXT = CheckByOSCurrentVersion
# Win32_NetworkAdapter is deprecated and not returning results on NanoServer
# Need to use MSFT_NetAdapter
if ((Get-Item "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server\ServerLevels").GetValue("NanoServer") -eq 1)
{
Import-module NetAdapter # In case the module is not loaded into PSEngine
$sQuery = "Win32_NetworkAdapter Where "
if ([System.Convert]::ToBoolean($IsUseMacAddress) -eq $true)
{
$sQuery += "MacAddress <> Null And ServiceName <> 'PptpMiniport' And ServiceName <> 'RasPppoe' And ServiceName <> 'VMSMP'"
}
else
{
$sQuery += "NetConnectionID <> Null And ServiceName <> 'VMSMP'"
}
# The Network Adapter information does not get populated correctly under Server 2008 Core.
# The NetConnectionStatus parameter is always NULL, so under Server 2008 Core this discovery
# will return all Network Adapters - both enabled and disabled.
# For more information see bugs "Windows OS Bugs", #2030782 & "Windows 7", #119223
if ([System.Convert]::ToBoolean($IsDiscoverDisabled) -eq $false)
{
$sQuery += " And NetConnectionStatus <> 0"
}
# If at least one network adapter has NetConnectionID then it is supported.
# In this case we should discover network adapters only with NetConnectionID <> "".
$IsCheckNetConnectionID = IsNetConnectionIDSupported $WMISetNetAdapter $false
foreach ($owObjNetAdapter in $WMISetNetAdapter)
{
$sNetConnectionID = $owObjNetAdapter.NetConnectionID
If ($boolUseWINVNEXT -eq $true)
{
# Checks if OS is at least Windows Server vNext
# Now get the Perfmon Instance Name
$WMISetPnPEntity = WMIExecQuery $sTargetComputer "root\cimv2" ("associators of {win32_NetworkAdapter='" + $sDeviceID + "'} where ResultClass=Win32_PnPEntity")
foreach ($owObjPnPEnt in $WMISetPnPEntity)
{
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.NetworkAdapter']/PerfmonInstance$", (GetPerfmonInstance $owObjPnPEnt.Name) )
}
# Now get the network adapter settings
$WMISetNetAdapterConfig = WMIExecQuery $sTargetComputer "root\cimv2" ("associators of {win32_NetworkAdapter='" + $sDeviceID + "'} where ResultClass=win32_NetWorkAdapterConfiguration")
foreach ($owObjNetAdpCnf in $WMISetNetAdapterConfig)
{
# Get DeviceID GUID for match with MSFT_NetAdapter
$KeySettingID = $owObjNetAdpCnf.SettingID
# Get the property value for SlotID from MSFT_NetAdapterHardwareInfoSettingData
$WMISetNetAdapterHrdwInfo = WMIGetInstance $sTargetComputer "root\StandardCimv2" ("MSFT_NetAdapterHardwareInfoSettingData where InstanceID='" + $KeySettingID + "'")
#******************************************************************************
# FUNCTION: CheckByOSCurrentVersion
# DESCRIPTION: Returns True if the Registry Key for CurrentVersion
# is equal the target OS Versions Number.
# RETURNS: Boolean: True, if build is greater or equal than the given number
#******************************************************************************
Function CheckByOSCurrentVersion() #As Boolean
{
$strCurrentOSVer = GetRegistryKeyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\" "CurrentVersion"