PowerShell中如何将JSON变量正确嵌入TMSL角色脚本的tablePermissions参数
PowerShell 生成合法TMSL脚本的正确实现方法
之前写法的核心错误
你之前的拼接逻辑存在两个根本性的格式问题,直接导致TMSL解析失败:
- 把PowerShell原生数组对象
$filter直接做字符串拼接时,PowerShell会把对象转成默认的类型名称字符串,根本不是合法的JSON数组结构 - 给
tablePermissions字段的值套了单引号,把原本应该是数组类型的字段值,变成了纯字符串类型,完全不符合TMSL的结构校验要求
推荐的稳定实现方式
绝对不要手动逐字符拼接JSON字符串,PowerShell原生的对象序列化能力可以自动处理结构、转义的问题,从根源上避免格式错误。
实现步骤
- 把传入的权限筛选变量(不管是从外部读的JSON字符串、还是脚本内定义的数组)先转成PowerShell原生对象:
# 如果你是从外部JSON文本读入的filter,执行下面这行转成原生对象 # $filter = $filterJsonString | ConvertFrom-Json - 按照TMSL的合法结构,用
PSCustomObject构建完整的脚本结构对象,直接把$filter作为tablePermissions字段的值嵌入,不需要做任何字符串处理:$tmslStructure = [PSCustomObject]@{ createOrReplace = [PSCustomObject]@{ object = [PSCustomObject]@{ database = "AW Internet Sales" role = "test_filter" } role = [PSCustomObject]@{ name = "test_filter" modelPermission = "read" # 直接嵌入数组变量,不要加引号 tablePermissions = $filter } } } - 把整个结构对象统一序列化为合法的JSON字符串,注意一定要指定足够的嵌套深度:
# 必须加-Depth参数,PowerShell默认深度为2,会截断嵌套结构 $Query = $tmslStructure | ConvertTo-Json -Depth 10
模板替换场景的适配方法
如果你的TMSL脚本很长,不想每次都从零构建对象,可以用模板占位符的方式实现参数化,注意两个核心规则:
- 写模板时,
tablePermissions字段的位置不要给值加引号,直接留占位符 - 嵌入变量前,先把
$filter转成合法的JSON片段,再替换占位符
示例代码:
# 把filter转成压缩格式的合法JSON片段 $filterJson = $filter | ConvertTo-Json -Depth 10 -Compress # 写模板,注意tablePermissions的值位置没有引号 $tmslTemplate = @' { "createOrReplace": { "object": { "database": "AW Internet Sales", "role": "test_filter" }, "role": { "name": "test_filter", "modelPermission": "read", "tablePermissions": {{filter_content}} } } } '@ # 替换占位符生成最终脚本 $Query = $tmslTemplate.Replace('{{filter_content}}', $filterJson)
常见避坑点
- 不要手动处理筛选表达式里的双引号转义,PowerShell的
ConvertTo-Json会自动完成所有转义逻辑,手动处理很容易出现漏转、错转的问题 - 不要依赖PowerShell默认的序列化深度,只要结构超过2层嵌套就一定要显式指定
-Depth,否则会出现数组值被替换成System.Object[]的低级错误 - TMSL对字段类型校验非常严格,只要把数组/对象类型的字段写成字符串类型,执行时会直接返回结构不匹配的错误
内容的提问来源于stack exchange,提问作者Michał Gosk
相关产品推荐
相关产品推荐

