首页 > 解决方案 > MECM、MEMCM、SCCM:手动导入硬件清单类 MOF 具有正确的命名空间,而以编程方式这样做不会

问题描述

奇怪的情况。我正在尝试以编程方式扩展硬件库存。我的MOF叫做“MyHINV.mof”,内容如下:

#pragma namespace ("\\\\.\\root\\cimv2")
#pragma deleteclass("MyNewHINVClass", NOFAIL)
[SMS_Report(TRUE),SMS_Group_Name("MyNewHINVClass"),SMS_Class_ID("MyNewHINVClass")]
Class MyNewHINVClass: SMS_Class_Template
{
[SMS_Report(TRUE),key] string KeyName;
[SMS_Report(TRUE)] String Stuff;
[SMS_Report(TRUE)] String Things;
};

当我通过控制台手动导入时,它会正确导入,并且在导出所有 HINV 设置时会看到以下内容:

[ SMS_Report (TRUE),
  SMS_Group_Name ("MyNewHINVClass"),
  SMS_Class_ID ("MyNewHINVClass"),
  Namespace ("\\\\\\\\.\\\\root\\\\cimv2") ]
class MyNewHINVClass : SMS_Class_Template
{
    [ SMS_Report (TRUE), key ]
    String     KeyName;
    [ SMS_Report (TRUE) ]
    String     Stuff
    [ SMS_Report (TRUE) ]
    String     Things
};

但是,当我以编程方式(使用 PowerShell 或 C#)导入时,命名空间会在末尾附加“sms”!

[ SMS_Report (TRUE),
  SMS_Group_Name ("MyNewHINVClass"),
  SMS_Class_ID ("MyNewHINVClass"),
  Namespace ("\\\\\\\\.\\\\root\\\\cimv2\\\\sms") ]
class MyNewHINVClass : SMS_Class_Template
{
    [ SMS_Report (TRUE), key ]
    String     KeyName;
    [ SMS_Report (TRUE) ]
    String     Stuff
    [ SMS_Report (TRUE) ]
    String     Things
};

到底是什么原因造成的?

这是我正在使用的 PowerShell,它成功导入但命名空间附加了“sms”:

[string]$HardwareInventoryReportID = "{00000000-0000-0000-0000-000000000001}"
[int]$ImportType = 3
[string]$NameSpace = "root\sms\site_p01"
[string]$Class = "SMS_InventoryReport"
[string]$Method = "ImportInventoryReport"

$mof = @"
#pragma namespace ("\\\\.\\root\\cimv2")
#pragma deleteclass("MyNewHINVClass", NOFAIL)
[SMS_Report(TRUE),SMS_Group_Name("MyNewHINVClass"),SMS_Class_ID("MyNewHINVClass")]
Class MyNewHINVClass: SMS_Class_Template
{
[SMS_Report(TRUE),key] string KeyName;
[SMS_Report(TRUE)] String Stuff;
[SMS_Report(TRUE)] String Things;
};
"@

$mc = [wmiclass]"\\$env:COMPUTERNAME\$NameSpace`:$Class"

$inparams = $mc.PSBase.GetMethodParameters($Method)
$inparams.InventoryReportID = $HardwareInventoryReportID
$inparams.ImportType = $ImportType
$inparams.MofBuffer = $mof

$result = $mc.PSBase.InvokeMethod($Method,$inparams,$null)

这是我正在使用的 C#;同样,这会正确导入,但会将“sms”附加到命名空间(注意,我正在使用 C# 控制台应用程序导入文件名并获得相同的结果):

using System;
using System.IO;
using System.Management;
namespace InventoryImporter
{
    class Program
    {
        public const string HardwareInventoryReportID = "{00000000-0000-0000-0000-000000000001}";

        static void Main(string[] args)
        {
            if (args != null && args.Length >= 2)
            {
                string fileName = args[0];
                string siteCode = args[1];
                ImportInventoryReport(siteCode, fileName);
            }
            else
            {
                Console.WriteLine("Usage: InventoryImportExample <MofFileName> <site code>");
            }

            Console.WriteLine("Press any key to exit");
            Console.ReadLine();
        }

        public static void ImportInventoryReport(string siteCode, string fileName, string inventoryReportID = HardwareInventoryReportID, InventoryImportType importOption = InventoryImportType.BothClassAndReport)
        {
            if (File.Exists(fileName) == false)
            {
                throw new FileNotFoundException("MOF file not found", fileName);
            }

            string mofToImport = File.ReadAllText(fileName);

            // Get the SMS_InventoryReport class.        
            try
            {
                string scope = string.Format(@"root\sms\site_{0}", siteCode);
                ManagementClass cls = new ManagementClass(scope, "SMS_InventoryReport", null);
                ManagementBaseObject inParams = cls.GetMethodParameters("ImportInventoryReport");
                inParams["InventoryReportID"] = inventoryReportID;
                inParams["ImportType"] = (uint)importOption;
                inParams["MofBuffer"] = mofToImport;
                ManagementBaseObject retVal = cls.InvokeMethod("ImportInventoryReport", inParams, null);

                // Get current site code.            
                uint resultCode = (uint)retVal["StatusCode"];
                if (resultCode == 0)
                {
                    Console.WriteLine("ImportInventoryReport for file {0} succeed ", fileName);
                }
                else
                {
                    Console.WriteLine("ImportInventoryReport for file {0} failed with error code:{1} ", fileName, resultCode);
                }
            }
            catch (ManagementException e)
            {
                Console.WriteLine("Failed to execute method ImportInventoryReport for file {0}: {1}", fileName, e.ToString());
            }
        }

        public enum InventoryImportType
        {
            ClassOnly = 1,
            ReportOnly = 2,
            BothClassAndReport = 3
        }
    }
}

这里到底发生了什么?

标签: c#powershellsccmconfigurationmanager

解决方案


推荐阅读