我要做什么
我正在尝试在Windows上使用AWS CLI将PowerShell脚本从GitHub存储库中提取到AWS EC2实例上,然后在该实例上运行该脚本。
我尝试过的事情
我知道转义的双引号(\“)是有效的,因为我尝试了将双引号(\”)无效。我还尝试将--parameters之后的JSON部分放在单独的文件中,然后将该文件加载到命令,但是在这种情况下它抱怨格式化。
我已经在PowerShell和Windows CMD中尝试了该命令(两者的语法不同,即使用双引号)。我在下面列出了这两种版本。
使用AWS EC2控制台,我可以使用图形界面来完成所有这些工作。现在的关键是使它也可以使用命令行工作。
以下是PowerShell的命令:
aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=<INSTANCE-ID>" --parameters '{\"sourceType\":[\"GitHub\"],\"sourceInfo\":{\"owner\":\"<USERNAME>\",\"repository\":\"Projects\",\"path\":\"test_script.ps1\"},\"commandLine\":[\".\\test_script.ps1\"],\"workingDirectory\":[""],\"executionTimeout\":[\"3600\"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region us-east-2
问题似乎来自--parameters参数及其后的JSON。
以下是Git Bash的命令(实际上有效):
aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=<INSTANCE-ID>" --parameters '{"sourceType":["GitHub"],"sourceInfo":["{\"owner\": \"<USERNAME>\", \"repository\": \"Projects\", \"path\": \"test_script.ps1\"}"],"commandLine":[".\\test_script.ps1"],"workingDirectory":[""],"executionTimeout":["3600"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region us-east-2
这是导致的错误:
Parameter validation failed: Invalid type for parameter Parameters.sourceInfo, value: OrderedDict([('owner', '<USERNAME>'), ('repository', 'Projects'), ('path', 'test_script.ps1')]), type: <class 'collections.OrderedDict'>, valid types: <class 'list'>, <class 'tuple'>
如何以适当的格式指定这些参数?
答案 0 :(得分:0)
PowerShell或CMD.exe存在一些JSON解析问题,同一命令在Linux Shell中也可以正常工作:
aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=mi-012dcb3ecea45b678" --parameters '{"sourceType":["GitHub"],"sourceInfo":[" {\n \"owner\":\"<user>\",\n \"repository\":\"<my-repo>\",\n \"path\":\"get-param.ps1\",\n \"getOptions\":\"branch:master\",\n \"tokenInfo\":\"{{ssm-secure:<my-token>}}\"\n }"],"commandLine":["get-param.ps1"],"workingDirectory":[""],"executionTimeout":["3600"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region eu-west-1
我实际上已经与awscli团队打开了这个问题,他们确认了Windows的这种解析限制,请检查:https://github.com/aws/aws-cli/issues/4212#issuecomment-507378423
因此,如果您使用相同的方法来使用json文件中的参数,则可以按照以下步骤进行操作:
使用以下内容创建param.json文件:
{
"sourceType": [
"GitHub"
],
"sourceInfo": [
" {\n \"owner\":\"<user>\",\n \"repository\":\"<repo>\",\n \"path\":\"get-param.ps1\",\n \"getOptions\":\"branch:master\",\n \"tokenInfo\":\"{{ssm-secure:<token>}}\"\n }"
],
"commandLine": [
"get-param.ps1"
],
"workingDirectory": [
""
],
"executionTimeout": [
"3600"
]
}
这时您应该能够运行以下命令:
aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=mi-012dcb3ecea45b678" --parameters file://param.json --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region eu-west-1
这将从cmd.exe和PowerShell中运行
答案 1 :(得分:0)
您总是可以发疯(就像我一样),然后对内容进行两次转义。 参数的值应该是代表json的字符串,该字符串包含一个属性,该属性是代表json的字符串的集合。
我是认真的。
aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=<INSTANCE-ID>" --parameters '{\"sourceType\":[\"GitHub\"],\"sourceInfo\":[\"{\\\"owner\\\":\\\"<USERNAME>\\\",\\\"repository\\\":\\\"Projects\\\"}\"],\"commandLine\":[\".\\test_script.ps1\"],\"workingDirectory\":[""],\"executionTimeout\":[\"3600\"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region us-east-2
因此,这里的整个技巧是通过在正确的位置将已转义的反斜杠\\
放在已转义的引号\"
之前来创建转义的反斜杠。
答案 2 :(得分:0)
使用PowerShell Send-SSMCommand cmdlet,我发现最简单的方法是splatting命令,而不用担心封装和转义(尽可能多)
$mySSMCommand = @{
ProfileName = 'default'
DocumentName = 'DocumentName'
Target = @{Key='InstanceIds'
Values=@('i-ABCDEFG')}
Parameter = @{
sourceType='S3'
sourceInfo='{"path": "https://bucketbucketbucket.s3-us-west-2.amazonaws.com/somescript.ps1"}'
commandLine='somescript.ps1 -MyParam "value"'
}
}
Send-SSMCommand @mySSMCommand