You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过C#修改现有任务序列的SMS_TaskSequencePackage安全作用域

修改Configuration Manager任务序列安全作用域的正确方法

我明白你遇到的问题了——SecuredScopeNames属性确实没法直接修改,它在Configuration Manager里是只读的安全属性,直接赋值肯定会失败。要修改任务序列的安全作用域,得通过SMS_ObjectContainerItem类来管理对象和安全作用域的关联关系,而不是直接操作SMS_TaskSequencePackage实例。

下面是完整的可运行C#方法,包含替换/更新安全作用域的逻辑:

public void SetSecurityScopes(WqlConnectionManager connection, string packageID, string[] newSecurityScopeNames)
{
    try
    {
        // 1. 获取目标任务序列包的实例,拿到它的唯一标识Key
        IResultObject taskSequencePackage = connection.GetInstance($"SMS_TaskSequencePackage.PackageID='{packageID}'");
        string packageKey = taskSequencePackage["PackageID"].StringValue;
        string objectTypeID = taskSequencePackage["__CLASS"].StringValue; // 固定返回"SMS_TaskSequencePackage"

        // 2. 查询当前关联的安全作用域,先删除旧的关联(如果需要替换而非追加)
        string query = $"SELECT * FROM SMS_ObjectContainerItem WHERE InstanceKey='{packageKey}' AND ObjectType='{objectTypeID}'";
        IResultObject existingScopes = connection.QueryProcessor.ExecuteQuery(query);

        foreach (IResultObject scope in existingScopes)
        {
            scope.Delete();
        }

        // 3. 遍历新的安全作用域,创建新的关联
        foreach (string scopeName in newSecurityScopeNames)
        {
            // 先通过名称获取安全作用域的ID(关联用ID而非名称)
            IResultObject scopeQuery = connection.QueryProcessor.ExecuteQuery($"SELECT ScopeID FROM SMS_SecuredCategory WHERE CategoryName='{scopeName}'");
            string scopeId = null;

            foreach (IResultObject scope in scopeQuery)
            {
                scopeId = scope["ScopeID"].StringValue;
                break;
            }

            if (string.IsNullOrEmpty(scopeId))
            {
                throw new Exception($"找不到名为{scopeName}的安全作用域");
            }

            // 创建新的对象-作用域关联实例
            IResultObject newScopeAssociation = connection.CreateInstance("SMS_ObjectContainerItem");
            newScopeAssociation["InstanceKey"].StringValue = packageKey;
            newScopeAssociation["ObjectType"].StringValue = objectTypeID;
            newScopeAssociation["ContainerNodeID"].IntegerValue = 0; // 使用默认容器节点
            newScopeAssociation["SecuredCategoryID"].StringValue = scopeId;

            // 提交关联设置
            newScopeAssociation.Put();
        }

        Console.WriteLine("安全作用域更新成功!");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"更新安全作用域失败: {ex.Message}");
        throw;
    }
}

关键要点说明:

  • 为什么不能直接改SecuredScopeNames:这个属性是Configuration Manager自动生成的只读属性,仅用于展示当前关联的安全作用域名称,实际的关联关系存储在SMS_ObjectContainerItem表中。
  • 替换vs追加逻辑:上面的代码会先删除所有旧的安全作用域关联,再添加新的。如果你只想追加新作用域,去掉删除旧关联的那段循环即可。
  • 安全作用域的绑定规则:必须通过安全作用域名称查询到对应的ScopeID,因为系统内部是用ID来绑定对象和作用域的,名称只是展示用的。
  • 异常处理:代码里包含了作用域不存在、任务序列包找不到等场景的异常捕获,避免程序意外崩溃。

调用这个方法时,传入的newSecurityScopeNames应该是字符串数组,比如new string[] {"Global", "Department-Scope"},这样就能批量设置多个安全作用域了。

内容的提问来源于stack exchange,提问作者Arnaud Lord Sesstyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:48:34