Нужна помощь с использованием кода на C # для выполнения последовательности задач SCCM

#c# #sccm

#c# #sccm

Вопрос:

Я начну с того, что я очень мало знаю о кодировании на C #. Очень хорошо работает с PowerShell, VBS и т.д. Но я могу, по крайней мере, знать достаточно, чтобы быть опасным. У нас есть программа на C #, которая выполняется локально на компьютере. Его цель — установить клиент SCCM и выполнить поиск объявленной последовательности задач. для целей этого упражнения предположим, что правильная последовательность задач развернута в коллекции, в которой находится этот компьютер — я знаю, что это не так — он запускает блок If, потому что находит объявленные TS.

В коде много других вещей, но вот мясо и картофель той части скрипта, которая терпит неудачу. Черт возьми, это в блоке try / catch, а имя TS — «Обновление Windows 10». Я даже переименовал TS, думая, что именно пробелы в нем привели к сбою. Никакой радости.

 ManagementScope scope = new ManagementScope(@"\localhostROOTccmclientsdk");
ObjectQuery query = new ObjectQuery("SELECT * FROM CCM_Program");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
Write_Log("Searching for Policy");

ManagementObjectCollection allpackages = searcher.Get();
     foreach (ManagementObject pkg in allpackages)
     {
          Write_Log(pkg["PackageName"].ToString());
          if (pkg["PackageName"].ToString() == "Windows 10 Upgrade")
          {
               Write_Log("Found:"   pkg["PackageName"].ToString());
               Write_Log("About to execute WMI Invoke for pkg: "   pkg);
               ManagementClass wmiClass = new managementClass(@"\localhostROOTccmclientSDK:CCM_ProgramsManager");
               ManagementBaseObject outMPParams = wmiClass.InvokeMethod("ExecuteProgram", pkg, null);
               Write_Log("ExecuteProgram Result: "   outMPParams["ReturnValue"].ToString());
               if (outMPParams["ReturnValue"].ToString() == "0")
                    Write_Log("SCCM TS Started");
                    Application.Exit();
                }
  

Локальный хост преобразуется в имя компьютера, так что это хорошо. Часть, которая терпит неудачу, заключается в следующем:

 ManagementBaseObject outMPParams = wmiClass.InvokeMethod("ExecuteProgram", pkg, null);
  

Теперь он полностью выходит из блока try / catch с «TS not found» и без каких-либо других ошибок. Что расстраивает, так это то, что я загрузил кучу записей Write_log, чтобы попытаться определить, в чем ошибка, но этот один шаг действительно хорошо разбивает ее и переходит прямо к блоку catch.

Есть ли у кого-нибудь опыт использования C # для задач, связанных с SCCM? Правильно ли выглядит приведенный выше синтаксис?

Как я уже сказал, я унаследовал код от другой компании и пытаюсь заставить его работать на нас. Я просто недостаточно знаю о вызове и не могу найти ничего в Интернете о том, что он пытается сделать.

Любая помощь ОЧЕНЬ приветствуется!!

Комментарии:

1. Это выглядит несколько корректно. Imo проблема в том, что у CCM_Program, похоже, нет никаких методов, поэтому вы не можете их вызвать. Из быстрого поиска я понял, что вам нужно будет получить TS из CCM_Program, а затем использовать CCM_ProgramsManager для выполнения (см.: social.technet.microsoft.com/Forums/en-US / … ) Поскольку это все wmi, и вы сказали, что хорошо разбираетесь в PS / VBS, я бы посоветовал сначала написать это на языке, который вы знаете, а затем «порт» на c #, как только это сработает.

2. Еще одна общая вещь: у TS не будет правильного имени (будет *), и даже PackageName может быть не тем, что вы ожидаете, используйте какой-нибудь WMIExplorer, чтобы вручную проверить, что это на самом деле и как его правильно идентифицировать

Ответ №1:

Ну, это не тот ответ, который я искал, но я смог собрать некоторый PS-код, который делает то, что мне нужно. Сначала я спрашиваю, какие пакеты доступны с этим:

 $AllPackages = Get-WmiObject -Class ccm_program -Namespace rootccmClientSDK 
  

Затем я щекочу машинную политику следующим образом

 Invoke-WMIMethod -Namespace rootccm -Class SMS_CLIENT -Name TriggerSchedule “{00000000-0000-0000-0000-000000000021}” | out-null
  

подождите немного, а затем оцените его с помощью этого:

 Invoke-WMIMethod -Namespace rootccm -Class SMS_CLIENT -Name TriggerSchedule “{00000000-0000-0000-0000-000000000022}” | out-null
  

затем я выполняю цикл ForEach, чтобы получить указанную информацию:

 ForEach ($Pkg in $AllPackages) {
     $PackageID = $Pkg.PackageID
     $ProgramID = $Pkg.ProgramID
     $PackageName = $Pkg.PackageName

     if ($PackageName -eq $TSName) {
  

Затем ET звонит домой с

 ([wmiclass]'rootccmClientSDK:CCM_ProgramsManager').ExecuteProgram($ProgramID, $PackageID)
  

и это все, что она написала. Я делаю все это в блоке While и отключаюсь после его запуска.

У меня есть один вопрос, если кто-нибудь все еще смотрит…

Как я могу получить результат от вызова WMI? Я попробовал это

 $RetVal=(([wmiclass]'rootccmClientSDK:CCM_ProgramsManager').ExecuteProgram($ProgramID, $PackageID)).ExitCode
  

Но ему это не понравилось. Возвращает ли это действие значение?

Спасибо за вашу помощь!

Комментарии:

1. Метод ExecuteProgram (s) должен возвращать значение 0 для успеха, отличное от нуля для ошибки ( learn.microsoft.com/en-us/mem/configmgr/develop/reference/core /… ). По какой причине вы считаете, что это должен быть exitcode? Я думаю, что стандартным возвращаемым значением для вызова wmi будет свойство с именем returnValue . Однако, если вы просто вызываете его без указания какого-либо свойства (или даже без его назначения, просто просматривая стандартный вывод), вы должны иметь возможность просто увидеть, как это действительно называется в вашем случае.