2

We're trying to use the REST API of Administration Service to manage the Configuration Manager (What is the administration service in Configuration Manager?)

We have successfully queried entities of different types and executed some custom static methods (i.e. MoveMembers Method on SMS_ObjectContainerItem). It's all mostly blind shots as there is barely any documentation, but those basic functionalities seem to work fine.

Now we have hit the wall, trying to add collection rules to a SMS_Collection (existing or new). This was normally done calling the AddMembershipRule on the instance itself, that was previously fetched by e.g. WqlConnectionManager or some other proxy. However, this is clearly a no-go on a plain object fetched from the REST service.

We have tried to use the wmi OData service (by a generated proxy) as it clearly offers similar functionality, but this ends up with a "Not supported exception":

var savedCollection = Proxy.SMS_Collection.Where(c => c.CollectionID == result.CollectionID).FirstOrDefault();
savedCollection.AddMembershipRule(inclusionRule);
Proxy.UpdateObject(savedCollection);
Proxy.SaveChanges();  //EXCEPTION

I have tried running POST request in numerous ways, using urls like:

SMS_Collection.AddMembershipRule?CollectionID=DV000037  -> 404    
SMS_Collection/DV000037/AddMembershipRule  -> 404
SMS_Collection.DV000037.AddMembershipRule  -> 404
SMS_Collection/DV000037.AddMembershipRule  -> treated it as post to SMS_Collection/DV000037, and therefore triggers an update

or just

SMS_Collection.AddMembershipRule with collectionID as param

As for the request body I've used (or just the AddCollectionMembershipRuleRequestRule):

    public class AddCollectionMembershipRuleRequest
    {
          public AddCollectionMembershipRuleRequestRule CollectionRule { get; set; }
    }

    public class AddCollectionMembershipRuleRequestRule
    {
        public string RuleName { get; set; }
        public string IncludeCollectionID { get; set; }
    }

I have also tried to Post an existing or new collection, with CollectionRules prefilled, but this ends up with an exception complaining about IncludeCollectionID not being part of CollectionRule (base class) - looks like validation being too strict and not dealing well with the inheritance.

    var collectionRequest = new ECMCollectionCreationRequest()
    {
        Name = collectionName,
        CollectionType = 2,
        RefreshType = 4,
        LimitToCollectionID = DefaultLimitingCollectionID,
        CollectionRules = new List<SMS_CollectionRule>()
        {
            new SMS_CollectionRuleIncludeCollection()
            {
                RuleName = "MembershipRule",
                IncludeCollectionID = "DV100020"
            }
        }
    };

Stil, no luck with any of those. Do you have any idea if such a scenario (modification of CollectionRules) is even supported with the Rest /OData service? If so, what would be the right way to achieve so?

mikus
  • 3,042
  • 1
  • 30
  • 40

2 Answers2

1
$Rule="{'collectionRule':{`"@odata.type`": `"#AdminService.SMS_CollectionRuleDirect`", `"ResourceClassName`": `"SMS_R_System`", `"ResourceID`": $DeviceID,`"RuleName`": `"$MachineName`"}}"

$RuleCreated = (Invoke-RestMethod -Method Post -Uri "https://$($CMProvider)/AdminService/wmi/SMS_Collection('$CollectionID')/AdminService.AddMembershipRule" -Body $Rule -ContentType 'application/json' -Credential $Cred)
vimuth
  • 5,064
  • 33
  • 79
  • 116
Eli
  • 11
  • 1
  • to be honest I'm not working on that solution anymore, but could you provide any more description than just this code? It's kind of a standard we require at Stack Overflow. :) At least compare it to the existing solution above – mikus Mar 19 '23 at 16:14
  • Solved the issue for me, thanks! – mhouston100 Aug 29 '23 at 22:17
0

It looks like this part is simply not supported at the moment. Looking at the code it seems that the service is not interpreting the arguments properly and therefore causing validation issues.

However, the same can be achieved, in a bit less clean and structured way, using ManagementScope and ManagementObject

var scope = new ManagementScope(siteAddress);
scope.Connect();

using (ManagementObject collection = new ManagementObject(scope, new ManagementPath($"SMS_Collection.CollectionID='{collectionID}'"), new ObjectGetOptions()))
{
    if (collection == null)
        throw new Exception($"Unable to find collection with ID '{collectionID}'");

    collection.Get();

    using (ManagementBaseObject inParams = collection.GetMethodParameters("AddMembershipRule"))
    using (ManagementClass ruleClass = new ManagementClass(scope, new ManagementPath("SMS_CollectionRuleDirect"), new ObjectGetOptions()))
    using (ManagementObject rule = ruleClass.CreateInstance())
    {
        rule["ResourceClassName"] = "SMS_R_System";
        rule["ResourceID"] = ecmResourceID;
        rule["RuleName"] = machineName;

        inParams["collectionRule"] = rule;

        collection.InvokeMethod("AddMembershipRule", inParams, null);
    }
}

One can add and remove all the other rule types in similar way.

Another alternative is of course to use PowerShell. Sill, I hope that with one of the next iterations of the Administration Service, support of those methods will be added.

Similarly, there seems to be no way to add/remove application or package and import/export them, using the admin services or even in the way mentioned above.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
mikus
  • 3,042
  • 1
  • 30
  • 40