将具有特殊字符的支柱变量传递给 Salt 时出错 cmd.script

Error passing a pillar variable with special characters to Salt's cmd.script

我正在使用 cmd.script 和 Powershell 作为 shell 使用 Salt 做一些自动化。将参数传递给状态模块时,出现错误 " 无法处理参数 'Conn_String' 的参数转换。无法将值转换为类型 System.String。" 我看到这个错误可以在常规 powershell 脚本中解决,方法是将作为参数传递的变量用单引号 ('') 包装起来,但我不知道如何在盐状态文件中实现相同的行为使用 jinja 设置变量的位置如下所示。如果我将 Conn_String 括在单引号中,例如 "-Conn_String" + 'Conn_String' 在 args 中,当我写主机而不是实际的连接字符串时,我会在 PowerShell 中得到 Conn_String 。感谢您帮助解决这个问题。

这是我的状态和 PowerShell 脚本的示例:

# pillar info in state
# content of Conn_String is "Server=testServer,2022;database=exampleDatabase;Integrated Security=SSP"

{% set var1 = pillar['var1'] %}
{% set var2 = pillar['var2'] %}
{% set Conn_String = pillar['Conn_String'] %}
{% set args = " -var1 " + var1 + " -var2 " + var2 + " -Conn_String " + Conn_String %}

CallPowerShell:
  cmd.script: 
    - source: {{ salt:// + pillar['var1'] + "/scripts/sendmail.ps1" %}
    - shell: powershell
    -cwd: D:\
    - args: {{ args }} 



# The PowerShell script(sendmail.ps1) that is called
param(
     [Parameter(Mandatory)]
     [string]$var2
     
     [Parameter(Mandatory)]
     [string]$Conn_String
     )
     Write-Host "$Conn_String"
     ...



我最终在分号处拆分字符串并用下划线连接它,因为 Powershell 将字符串中的分号解释为命令分隔符。这是一种解决方法——我仍然更喜欢一种无需任何操作即可传输此字符串的方法。这是我现在的解决方法。

...
{% set Conn_String = pillar['Conn_String'].split(' ') | join('_') %} # this add _ to Integrated Security=SSPI
{% set Temp_Conn_String = Conn_String.split(';') | join('_') %} # handles the ; in "Server=testServer,2022;database=exampleDatabase;Integrated_Security=SSP"
{% set args = ... + var2 + " -Temp_Conn_String " + Temp_Conn_String %}



param(
     $var2,
     $Temp_Conn_String
     )
     # With this I'm able to retrieve the original connection string
     $Conn_String = $Temp_Conn_String -split " " -join "," -split "_",3 -join ";" -split "_" -join " "
     Write-Host "$Conn_String"


在每个级别,Jinja2 然后是 YAML,您需要确保您有一个有效的字符串,其中包含单引号:

{% set args = " -var1 '" ~ var1 ~ "' -var2 '" ~ var2 ~ "' -Conn_String '" ~ Conn_String ~ "'" %}

Call PowerShell:
  cmd.script: 
    - source: "salt://{{ var1 }}/scripts/sendmail.ps1"
    - shell: powershell
    - cwd: D:\
    - args: {{ args|yaml_dquote }}

或者,没有中间变量:

Call PowerShell:
  cmd.script: 
    - source: "salt://{{ pillar['var1'] }}/scripts/sendmail.ps1"
    - shell: powershell
    - cwd: D:\
    - args: "-var1 '{{ pillar['var1'] }}' -var2 '{{ pillar['var2'] }}' -Conn_String '{{ pillar['Conn_String'] }}'"

如果某些变量也可能包含引号,那么您应该添加 |yaml_encode 过滤器以确保它们是 \-转义的。