1

I am trying to update SCCM SMS_TaskSequence_Action classes in WMI using C#. I can successfully enumerate SMS_TaskSequence_Step classes completely; but I cannot seem to modify and/or "update" WMI the way I'd expect.


I am using a .NET 4.7.2 Console application, including references to the AMD64-specific "adminui.wqlqueryengine.dll" and "microsoft.configurationmanagement.managementprovider.dll" libraries.

I expected that I could use IResultObject.Get() and .Put(), but they're throwing "System.NotImplementedException". I can use SetArrayItems() on the ts (Task Sequence) object, but the changes don't appear to be applying.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.ConfigurationManagement.ManagementProvider;
using Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine;

namespace SCCM
{
    class Program
    {
        static Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine.WqlConnectionManager wqlcm;

        static void Main(string[] args)
        {
            wqlcm = new WqlConnectionManager();
            wqlcm.Connect("ServerName");

            IResultObject taskSequencePackages = wqlcm.QueryProcessor.ExecuteQuery("select * from SMS_TaskSequencePackage");

            foreach (IResultObject tsp in taskSequencePackages)
            {
                tsp.Get();
                //tsp["Name"].StringValue = "Setting a custom Task Sequence Package Name";
                //tsp.Put();

                Console.WriteLine("Task Sequence Name: " + tsp["Name"].StringValue);
                Console.WriteLine("Sequence: " + tsp["Sequence"].StringValue);

                Dictionary<string, object> parameters = new Dictionary<string, object>();
                parameters.Add("TaskSequencePackage", tsp);

                IResultObject sequence = wqlcm.ExecuteMethod("SMS_TaskSequencePackage", "GetSequence", parameters);
                IResultObject ts = sequence.GetSingleItem("TaskSequence");

                // Get a list of steps.  
                List<IResultObject> actionSteps = ts.GetArrayItems("Steps");

                // Find the action to be deleted.  
                foreach (IResultObject actionStep in actionSteps)
                {
                    if (actionStep["__CLASS"].StringValue == "MyCustomTaskSequenceAction" && actionStep["__SUPERCLASS"].StringValue == "SMS_TaskSequence_Action")
                    {
                        // Throws a "System.NotImplementedException": The method or operation is not implemented.  
                        //actionStep.Get();

                        actionStep["CommandLine"].StringValue = "Some New Command Line";

                        ts.SetArrayItems("Steps", actionSteps);
                        break;
                    }
                }
            }
        }
    }
}

I am also aware that an SMS_TaskSequencePackage class contains a single SMS_TaskSequence, and from it, I can retrieve the SMS_TaskSequence_Step classes that make up a Task Sequence. I also know that I'll need to enumerate the steps recursively (following the SDK) because a Step can be an SMS_TaskSequence_Action or any number of nested SMS_TaskSequence_Group objects.

Assuming I recurse through all of the steps, how does one make changes to the specific SMS_TaskSequence_Action classes they want to change and apply them properly? Using .Get() and .Put() works on the tsp object, but I can't seem to figure out how to update steps.

Justin Shidell
  • 588
  • 1
  • 5
  • 16

1 Answers1

2

I think what you are missing is a call to SetSequence after the SetArrayItems so you just finalized the steps but did not save the new steps to the ts, so you would need something like:

Dictionary<string, object> inParams = new Dictionary<string, object>();  
inParams.Add("TaskSequence", ts);  
inParams.Add("TaskSequencePackage", tsp);  

// Associate the task sequence with the package. Note that a call to Put is not required.  
IResultObject result = connection.ExecuteMethod("SMS_TaskSequencePackage", "SetSequence", inParams); 

I could not find a good example for your use case in english and c# but this german powershell tutorial (code is commented in english, saving is done in 5th step) leads me to believe it has to be done this way.

Syberdoor
  • 2,521
  • 1
  • 11
  • 14