@echo off
set psscript=PrintServerRole.Discovery.ps1
set vbscript=PrintServerRole.Discovery.vbs
set cscript=%windir%\system32\cscript.exe
set ps=%windir%\system32\WindowsPowerShell\v1.0\powershell.exe
set params=
if Exist "%cscript%" goto vb
if Exist "%ps%" goto pshell
goto end
:vb
if not exist "%~dp0%vbscript%" goto end
if exist "%~dp0vbparams.txt" (
set /p params=<"%~dp0vbparams.txt"
)
"%cscript%" /nologo "%~dp0%vbscript%" %params%
goto end
:pshell
if not exist "%~dp0%psscript%" goto end
if exist "%~dp0psparams.txt" (
set /p params=<"%~dp0psparams.txt"
)
"%ps%" -nologo -EP bypass -command "& '%~dp0%psscript%'" %params%
goto end
If ([string]::IsNullOrEmpty($SourceId) -or [string]::IsNullOrEmpty($ManagedEntityId) -or [string]::IsNullOrEmpty($TargetComputerId))
{
$message = "Invalid number of arguments or empty arguments."
$momAPI.LogScriptEvent($ScriptName, $EventId, $EventInformation, $message)
Function Init-ScomHelper
{
$DiscHelper = @'
namespace SCOM.Helper
{
using System;
using System.Runtime.InteropServices;
public class ConvertData
{
public static string GetDataItemFromOutput(
Object oData)
{
NativeMethods.ISerialize discoverySerializer = null;
discoverySerializer = oData as NativeMethods.ISerialize;
string xmlString = null;
if (null != discoverySerializer)
{
int hr = discoverySerializer.SaveToString(out xmlString);
Marshal.ThrowExceptionForHR(hr);
}
return xmlString;
}
public static class NativeMethods
{
[Guid("A4E79E8A-9494-47A4-A280-8C7D35C88A2F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISerialize
{
int SaveToString([MarshalAs(UnmanagedType.BStr)] out string output);
int LoadFromString([MarshalAs(UnmanagedType.BStr)] string input);
}
}
}
}
</Script></Contents>
<Unicode>true</Unicode>
</File>
<File>
<Name>PrintServerRole.Discovery.vbs</Name>
<Contents><Script>
'Copyright (c) Microsoft Corporation. All rights reserved.
' Parameters that should be passed to this script
' 0 MPElement ID
' 1 Target Id for ME this rule is running against
' 2 Computer (FQDN) that the OS will be hosted on
' 3 Computer ID (Key) that the OS will be hosted on
Const PrinterNameSpace = "winmgmts:\\.\root\cimv2"
Const PrinterRoleQuery = "SELECT Name FROM Win32_ServerFeature WHERE ID = 7"
Call Main()
Sub Main()
On Error Resume Next
Dim SourceId, ManagedEntityId, TargetComputer, TargetComputerId
Dim oAPI, oDiscoveryData
Dim result
Dim message
Dim IsExitWithSnapshot
IsExitWithSnapshot = False
Set oError = New Error
Err.Clear
Set oAPI = CreateObject("MOM.ScriptAPI")
If (0 <> Err.Number) Then
WScript.Quit()
End If
result = GetArguments(SourceId,ManagedEntityId,TargetComputer,TargetComputerId)
If (False = result) Then
message = "Invalid number of arguments or empty arguments."
Call oAPI.LogScriptEvent(ScriptName, EventId, EventInformation, message)
IsExitWithSnapshot = True
Err.Clear
End If
Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
If (0 <> Err.Number) Then
message = "Cannot create discovery data object."
Call oAPI.LogScriptEvent(ScriptName, EventId, EventError, message)
WScript.Quit()
End If
If (True = IsExitWithSnapshot) Then
oDiscoveryData.IsSnapShot = False
Else
If ( False = DoDiscovery(TargetComputer, TargetComputerId, oDiscoveryData) ) Then
Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
oDiscoveryData.IsSnapShot = False
End If
End If
Call oAPI.Return(oDiscoveryData)
End Sub
Function DoDiscovery(ByVal sTargetComputer, ByVal sTargetComputerID, ByVal oDisc)
Dim oInstance, InstallationType, WmiPrintRole
Dim LogName, nCount,DisplayName
DoDiscovery = False
On Error Resume Next
LogName = FullLogName
InstallationType = GetRegistryKeyValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\", "InstallationType")
InstallationType = LCase(InstallationType)
If (InstallationType = "server core") Then
LogName = CoreLogName
Else
If (InstallationType = "nano server") Then
DoDiscovery = True
Exit Function
End If
End If
Err.Clear
Set WmiPrintRole = WMIQuery(PrinterNameSpace,PrinterRoleQuery)
If (0 <> Err.number) Then
If ( WMI_ERROR_INVALIDCLASS = Err.number) Or (WMI_ERROR_INVALIDNAMESPACE = Err.number) Then
DoDiscovery = True
Set WmiPrintRole = Nothing
Err.Clear
Exit Function
Else
Set WmiPrintRole = Nothing
Exit Function
End If
End If
If (False = HasValue(WmiPrintRole)) Then
DoDiscovery = True
Set WmiPrintRole = Nothing
Err.Clear
Exit Function
End If
nCount = WmiPrintRole.Count
If (0 <> Err.number) Then
If ( WMI_ERROR_INVALIDCLASS = Err.number) Or (WMI_ERROR_INVALIDNAMESPACE = Err.number) Then
DoDiscovery = True
Set WmiPrintRole = Nothing
Err.Clear
Exit Function
Else
Set WmiPrintRole = Nothing
Exit Function
End If
End If
If (0 = nCount) Then
DoDiscovery = True
Set WmiPrintRole = Nothing
Err.Clear
Exit Function
End If
Set WmiPrintRole = Nothing
Set oInstance = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.10.0.PrintServerRole']$")
If Err.Number <> 0 Then
Set oInstance = Nothing
Exit Function
End If
DisplayName = "Windows Server 2016 Print Server (" & sTargetComputer & ")"
With oInstance
.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sTargetComputerID
.AddProperty "$MPElement[Name='Microsoft.Windows.Server.10.0.PrintServerRole']/EventLog$", LogName
.AddProperty "$MPElement[Name='System!System.Entity']/DisplayName$", DisplayName
End With
If Err.Number <> 0 Then
Exit Function
End If
Call oDisc.AddInstance(oInstance)
If 0 = Err.Number Then
DoDiscovery = True
End If
On Error Goto 0
End Function
Function GetArguments(ByRef SourceId,ByRef ManagedEntityId,ByRef sTargetComputer, ByRef sTargetComputerID)
On Error Resume Next
Err.Clear
GetArguments = False
Set objArguments = WScript.Arguments
If (Err.number <> 0) Then
Exit Function
End If
If (objArguments.Count < 4) Then
Exit Function
End If
If ( ( 0 <> Len(SourceId)) And (0 <> Len(sTargetComputerID)) And (0 <> Len(sTargetComputer)) And (0 <> Len(ManagedEntityId)) ) Then
GetArguments = True
End If
On Error Goto 0
End Function
Function GetRegistryKeyValue(ByVal keyPath, ByVal key)
Dim oReg, strKeyValue
strKeyValue = ""
GetRegistryKeyValue = strKeyValue
On Error Resume Next
Err.Clear
Set oReg = CreateObject("WScript.Shell")
If Err.Number <> 0 Then
Err.Clear
Exit Function
End If
strKeyValue = oReg.RegRead(keyPath & key)
If Err.Number <> 0 Then
Err.Clear
Exit Function
End If
GetRegistryKeyValue = strKeyValue
' resume error
On Error Goto 0
End Function
Function WMIQuery(ByVal sNamespace, ByVal sQuery)
Dim oWMI, oInstance, nInstanceCount
On Error Resume Next
Set WMIQuery = Nothing
Err.Clear
Set oWMI = GetObject(sNamespace)
If (Err.Number <> 0 ) Then
Set oWMI = Nothing
Exit Function
End If
If (False = HasValue(oWMI)) Then
Set oWMI = Nothing
Exit Function
End If
Set oInstance = oWMI.ExecQuery(sQuery)
If (Err.Number <> 0 ) Then
Set oWMI = Nothing
Set oInstance = Nothing
Exit Function
End If
If (True = HasValue(oInstance)) Then
'Determine if we queried a valid WMI class - Count will return 0 or empty
nInstanceCount = oInstance.Count
If Err.Number = 0 Then
Set WMIQuery = oInstance
On Error Goto 0
Exit Function
End If
End If
End Function
Function HasValue(Value)
Dim bNothing
bNothing = false
IF ( IsObject(Value) ) THEN
IF (Nothing is Value) THEN
bNothing = true
END IF
END IF
HasValue = Not ( IsEmpty(Value) or bNothing or IsNull(Value) )
End Function