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

如何在PowerShell二进制模块中覆盖Types.ps1xml类型定义

解决自定义ObjectSecurity子类被PowerShell内置类型定义覆盖的问题

问题根源

PowerShell的类型扩展基于继承链生效:内置Microsoft.PowerShell.Security模块的Types.ps1xml定义了针对System.Security.AccessControl.ObjectSecurity基类的扩展属性(比如AccessToString、Path),你的自定义子类会继承这些扩展。当内置模块被隐式加载(比如执行Get-Acl),它的类型定义会覆盖你之前加载的自定义扩展,导致原有属性被替换。

具体解决方法

1. 精准指定自定义类型的完整名称

在你的WindowsUtils.Types.ps1xml中,确保类型定义的TypeName是自定义类的完整命名空间+类名,而非基类。这样PowerShell只会将扩展应用到你的子类,不会影响基类或其他子类:

<Type>
  <Name>Your.Namespace.CustomObjectSecurity</Name>
  <Members>
    <ScriptProperty>
      <Name>Owner</Name>
      <GetScriptBlock>$this.GetOwner([System.Security.Principal.NTAccount])</GetScriptBlock>
    </ScriptProperty>
    <ScriptProperty>
      <Name>AccessToString</Name>
      <GetScriptBlock>/* 你的自定义逻辑 */</GetScriptBlock>
    </ScriptProperty>
    <!-- 其他自定义属性 -->
  </Members>
</Type>

2. 模块加载时优先加载自定义类型定义

在模块的.psm1文件末尾添加以下命令,强制让你的类型定义优先级高于内置模块:

Update-TypeData -PrependPath "$PSScriptRoot\WindowsUtils.Types.ps1xml"

-PrependPath会将你的类型定义插入到类型数据列表的最前面,后续加载的同类型扩展无法覆盖它。

3. 在C#类中显式实现属性(推荐)

如果能修改自定义类的C#代码,直接在类中添加同名属性,PowerShell会优先使用类的原生属性,完全避免类型扩展冲突:

using System.Security.AccessControl;
using System.Security.Principal;

namespace Your.Namespace
{
    public class CustomObjectSecurity : ObjectSecurity
    {
        // 显式实现Owner属性,覆盖基类逻辑
        public new string Owner => GetOwner(typeof(NTAccount)).Value;
        
        public new string Group => GetGroup(typeof(NTAccount)).Value;
        
        // 自定义AccessToString实现
        public new string AccessToString
        {
            get
            {
                // 你的自定义格式化逻辑
                var accessRules = GetAccessRules(true, true, typeof(NTAccount));
                return string.Join(Environment.NewLine, accessRules);
            }
        }
    }
}

使用new关键字覆盖基类的虚拟成员,确保PowerShell绑定到你的实现。

4. 移除内置模块的ObjectSecurity类型扩展(谨慎使用)

如果上述方法无效,可以移除内置模块对基类的扩展,但这会影响Get-Acl等系统Cmdlet的输出格式,需谨慎:

# 移除内置的ObjectSecurity类型扩展
Remove-TypeData -TypeName System.Security.AccessControl.ObjectSecurity
# 重新加载自定义类型
Update-TypeData -PrependPath "$PSScriptRoot\WindowsUtils.Types.ps1xml"

内容的提问来源于stack exchange,提问作者FranciscoNabas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:32:50