格式化 Ansible for PowerShell invoke-sqlcmd 命令中的转义文字引号



在这里联系社区。我正在使用 Ansible 脚本,并且需要将设置文件中的一些配置数据插入Microsoft SQL Server DB。这些设置在 XML 中指定。

设置 JSON 文件示例 (ConfigData.json(

{
"ConfigDataXML": "<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><PathSettings="Windows"></PathSettings></Settings>",
"ConfigDescription": "OS File Config",
"ConfigPermissions": "Readonly"
}

安斯布尔数据库插入

- name 'read config file into var'
include_vars:
file: ConfigData.json
name: configData
- name 'add config to DB'
win_shell: "invoke-sqlcmd -username "{{db_user}}" -password "{{db_pass}}" -Query "INSERT INTO ConfigData (Data, ConfigId) VALUES ({{ configData.ConfigDataXML}},'{{ item.configId }}')""

执行上述操作时,插入失败,因为 PowerShell invoke-sqlcmd 返回错误:

A positional parameter cannot be found that accepts argument 'http'

这是由于 XML 数据中已转义的文本双引号。PowerShell 要求任何双引号必须首先用反引号 "'" 转义,因此为了使上面的配置 XML 传递 PowerShell 语法规则,只要出现转义的双引号,它都需要反引号:

"ConfigDataXML": "<Settings xmlns:xsd=`"http://www.w3.org/2001/XMLSchema`" xmlns:xsi=`"http://www.w3.org/2001/XMLSchema-instance`"><PathSettings=`"Windows`"></PathSettings></Settings>"

问题:JSON 文件是静态的,因为它是从另一个系统读入的,因此无法更改。唯一的选择是让 Ansible 脚本解析 XML 字符串并添加反引号。我想知道如何在 Ansible 中实现这一目标。

只要 XML 不包含任何单引号,这应该可以工作:

- name 'add config to DB'
win_shell: |
Invoke-Sqlcmd -username "{{db_user}}" -password "{{db_pass}}" -Query "
INSERT INTO ConfigData (Data, ConfigId) 
VALUES ('{{ configData.ConfigDataXML }}', '{{ item.configId }}')
"

根据文档,|引入了一个多行 shell 命令,该命令消除了对括引号的需要,因此不需要任何其他引号转义。


如果您希望 XML 中包含单引号,或者只是为了安全起见,则可以像这样使用@"here-string"@语法(PowerShell 要求在开始@"之后和结束"@之前使用换行符,但在两者之间允许引号和换行符的任何组合,而无需进一步转义, 这对于可能包含任何内容的{{placeholders}}非常方便(:

- name 'add config to DB'
win_shell: |
$xmlstring = @"
{{ configData.ConfigDataXML }}
"@
$xmlstring = $xmlstring -replace "'","''"
Invoke-Sqlcmd -username "{{db_user}}" -password "{{db_pass}}" -Query "
INSERT INTO ConfigData (Data, ConfigId) 
VALUES ('$xmlstring', '{{ item.configId }}')
"

注意/警告这些都不能保护您免受恶意制作的ConfigDataXML值的侵害。对于您的使用上下文来说,这可能不是一个可能的情况,但"从字符串连接 SQL"仍然不干净。

最新更新