I came across this bash script and I need to do the same thing in PowerShell.
vault write ssh-client-signer/roles/my-role -<<"EOH"
{
"allow_user_certificates": true,
"allowed_users": "*",
"default_extensions": [
{
"permit-pty": ""
}
],
"key_type": "ca",
"default_user": "ubuntu",
"ttl": "30m0s"
}
EOH
I tried using a multiline string like so :
vault write ssh-client-signer/roles/my-role -#"
{
"allow_user_certificates": true,
"allowed_users": "*",
"default_extensions": [
{
"permit-pty": ""
}
],
"key_type": "ca",
"default_user": "ubuntu",
"ttl": "30m0s"
}
"#
But the command doesn't parse the option correctly.
Failed to parse K=V data: invalid key/value pair "-#\n{\n allow_user_certificates: true,\n allowed_users: *,\n default_extensions: [\n {\n permit-pty: \n": format must be key=value
I found a way to run my command with PowerShell by asking vault to read options from a JSON file.
vault write ssh/roles/my-role "#my-role.json";
But that does not answer the original question.
Here's the output from echoargs. It doesn't seem workable this way.
echoargs -#"
{
"allow_user_certificates": true,
"allowed_users": "*",
"default_extensions": [
{
"permit-pty": ""
}
],
"key_type": "ca",
"default_user": "ubuntu",
"ttl": "30m0s"
}
"#
Arg 0 is <-#
{
allow_user_certificates: true,
allowed_users: *,
default_extensions: [
{
permit-pty:
>
Arg 1 is <}
>
Arg 2 is <],
>
Arg 3 is <key_type:>
Arg 4 is <ca,
>
Arg 5 is <default_user:>
Arg 6 is <ubuntu,
>
Arg 7 is <ttl:>
Arg 8 is <30m0s
}
#>
You might have to backslash all the quotes, if you want to go through the trouble. If you can't pipe the json to it.
$myarg = #"
{
"allow_user_certificates": true,
"allowed_users": "*",
"default_extensions": [
{
"permit-pty": ""
}
],
"key_type": "ca",
"default_user": "ubuntu",
"ttl": "30m0s"
}
"# -replace '"','\"'
echoargs -$myarg
Arg 0 is <-{
"allow_user_certificates": true,
"allowed_users": "*",
"default_extensions": [
{
"permit-pty": ""
}
],
"key_type": "ca",
"default_user": "ubuntu",
"ttl": "30m0s"
}>
You're misunderstanding how the Bash example works, the actual command executed is
vault write ssh-client-signer/roles/my-role -
where the - is to read the value from stdin, and the <<"EOH" is the start of a heredoc.
For the PowerShell version, you're attempting to use a herestring (different from a heredoc), but because of the - it's being interpreted as a bare string.
Since PowerShell lacks input redirection, an equivalent command might be
#"
{
"allow_user_certificates": true,
"allowed_users": "*",
"default_extensions": [
{
"permit-pty": ""
}
],
"key_type": "ca",
"default_user": "ubuntu",
"ttl": "30m0s"
}
"# | vault write ssh-client-signer/roles/my-role -
Depending on how vault handles data it might also be possible to pass it directly as an argument
vault write ssh-client-signer/roles/my-role #"
{
"allow_user_certificates": true,
"allowed_users": "*",
"default_extensions": [
{
"permit-pty": ""
}
],
"key_type": "ca",
"default_user": "ubuntu",
"ttl": "30m0s"
}
"#
Related
I am trying to append a txt file with punctuations to text to a file in AHK but it seems to break the line even if i use round brackets. How can I append to a file without breaking it?
FileAppend, ({
"accounts": [
{
"active": true,
"type": "dummy",
"ygg": {
"extra": {
"clientToken": "123456789",
"userName": "BX0W"
},
"iat": 1655273051,
"token": "BX0W"
}
}
],
"formatVersion": 3
}), accounts.json
Try this instead. Even inside a function my experience with a continuation section is that the parentheses must be the beginning of each line (with no preceding whitespaces) for it to work. I am guessing that it has something to do with the compiler.
FileAppend,
(
{
"accounts": [
{
"active": true,
"type": "dummy",
"ygg": {
"extra": {
"clientToken": "123456789",
"userName": "BX0W"
},
"iat": 1655273051,
"token": "BX0W"
}
}
],
"formatVersion": 3
}
), accounts.json
I want to add multiple Principal values for a KMS key using CloudFormation. This is a snippet of the code:
"KmsKeyManager": {
"Type": "String",
"Default": "user1,user2,user3"
}
"Principal": {
"AWS": {
"Fn::Split": [
",",
{
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:user/people/${rest}",
{
"rest": {
"Fn::Join": [
"",
[
"arn:aws:iam::",
{
"Ref": "AWS::AccountId"
},
":user/people/",
{
"Ref": "KmsKeyManager"
}
]
...
The ARN should be constructed as arn:aws:iam::12345678:user/people/user1 etc.
The template is accepted in the console, but when running I get the following error:
Resource handler returned message: "An ARN in the specified key policy is invalid.
I followed the answer here which resulted in the above error
CloudFormation Magic to Generate A List of ARNs from a List of Account Ids
Any idea where I am going wrong? CloudFormation is new to me, so the alternative is I create with 1 user and add new users manually.
Let me explain from the answer you linked. They use the string ":root,arn:aws:iam::" as a delimiter.
Therefore,
"Accounts" : {
"Type" : "CommaDelimitedList",
"Default" : "12222234,23333334,1122143234,..."
}
"rest": {
"Fn::Join": [
":root,arn:aws:iam::",
{ "Ref": "Accounts" }
]
}
gives rest like this.
12222234:root,arn:aws:iam::23333334:root,arn:aws:iam::1122143234
and this rest is substituted for ${rest} in "arn:aws:iam::${rest}:root" (This long string will be split finally with "Fn::Split".)
In your case, delimiter will be "arn:aws:iam::${AWS::AccountId}:user/people/".
This is also need to be joined:
{
"Fn::Join": [
"", [
"arn:aws:iam::",
{
"Ref": "AWS::AccountId"
},
":user/people/"
]
]
}
The total will be like:
"Fn::Sub": [
"arn:aws:iam::${AWS::AccountId}:user/people/${rest}",
{
"rest": {
"Fn::Join": [
"Fn::Join": [
"", [
"arn:aws:iam::",
{
"Ref": "AWS::AccountId"
},
":user/people/"
]
],
{
"Ref": "KmsKeyManager"
}
]
}
}
]
I am trying to pass an array from an AzurePowerShell task to an ARM template but I am not sure how to do this.
I get the error:
Not valid json when I attempt to pass it as a string and then use json function in ARM although when I print the json out and lint it, it is valid json.
Can't convert string to object when the template expects an object.
Any help is appreciated.
I have a powershell script that grabs the access policies from my key vault:
$keyVault = Get-AzKeyVault -Name $keyVaultName -ResourceGroupName $resourceGroupName
$keyVaultAccessPolicies = $keyVault.AccessPolicies
$json = $keyVaultAccessPolicies | ConvertTo-Json -Compress
Write-Host "##vso[task.setvariable variable=SAUCE;isOutput=true;]$json"
EDIT
I can see the value when debugging to be an array as its surrounded by square brackets. However, when outputted in pipelines the square bracket is omitted out. I find this strange and don't understand why its doing that.
However, how do I now pass this to a template?
- task: AzureResourceManagerTemplateDeployment#3
displayName: 'Provision Key Vault'
inputs:
deploymentScope: 'Resource Group'
azureResourceManagerConnection: ${{ parameters.azureSubscriptionName }}
subscriptionId: ${{ parameters.azureSubscriptionId }}
action: 'Create Or Update Resource Group'
resourceGroupName: '$(Resource.Group.Name)'
location: '$(Region)'
templateLocation: 'Linked artifact'
csmFile: '$(Provisioning.Package.Name)/Templates/key-vault-deploy.json'
deploymentMode: 'Incremental'
overrideParameters: >-
-name "$(KeyVault.Name)"
-foo "$env:accesspolicyreference_SAUCE"
The is the key vault template
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"fooBar": {
"type": "string"
}
},
"variables": {
},
"resources": [
{
"apiVersion": "2018-02-14",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"type": "Microsoft.KeyVault/vaults",
"properties": {
"accessPolicies": "[json(parameters('fooBar'))]",
"enabledForDeployment": false,
"enabledForTemplateDeployment": true,
"enabledForDiskEncryption": false,
"enableRbacAuthorization": false,
"tenantId": "[parameters('tenant')]",
"sku": {
"name": "Standard",
"family": "A"
},
"enableSoftDelete": false,
"networkAcls": {
"defaultAction": "allow",
"bypass": "AzureServices",
"ipRules": [],
"virtualNetworkRules": []
}
},
"tags": "[variables('tags')]",
"dependsOn": []
}
],
"outputs": {}
}
There are several issues here:
Overriding an arm template parameter with a json string can get you into trouble, if it is not escaped correctly. I suggest, you encode the json as a base64 string:
$keyVault = Get-AzKeyVault -Name 'vaultbyenar2htogee'
$keyVaultAccessPolicies = $keyVault.AccessPolicies
$json = $keyVaultAccessPolicies | ConvertTo-Json -Compress
$sauce64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($json))
Write-Host "##vso[task.setvariable variable=SAUCE]$sauce64"
There is an arm template function base64ToJson() that directly decodes base64 encoded json strings into objects:
"variables": {
"fooBar": "[base64ToJson(parameters('fooBar'))]"
}
The object that you get from $keyVault.AccessPolicies is not a valid value for the accessPolicies property in the arm template. In order to make it work, you need to map the values into the correct structure with a copy-loop:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"fooBar": {
"type": "string"
}
},
"variables": {
"fooBar": "[base64ToJson(parameters('fooBar'))]"
},
"resources": [
{
"apiVersion": "2018-02-14",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"type": "Microsoft.KeyVault/vaults",
"properties": {
"copy": [ {
"name": "accessPolicies",
"count": "[length(variables('fooBar'))]",
"input": {
"tenantId": "[subscription().tenantId]",
"objectId": "[variables('fooBar')[copyIndex('accessPolicies')].ObjectId]",
"permissions": {
"keys": "[variables('fooBar')[copyIndex('accessPolicies')].PermissionsToKeys]",
"secrets": "[variables('fooBar')[copyIndex('accessPolicies')].PermissionsToSecrets]",
"certificates": "[variables('fooBar')[copyIndex('accessPolicies')].PermissionsToCertificates]"
}
}
}],
"enabledForDeployment": false,
"enabledForTemplateDeployment": true,
"enabledForDiskEncryption": false,
"enableRbacAuthorization": false,
"tenantId": "[subscription().tenantid]",
"sku": {
"name": "Standard",
"family": "A"
},
"enableSoftDelete": false,
"networkAcls": {
"defaultAction": "allow",
"bypass": "AzureServices",
"ipRules": [],
"virtualNetworkRules": []
}
},
"dependsOn": []
}
],
"outputs": {}
}
No need to use ;isOutput=true if you will use the pipeline variable in a downstream task within the same job. (Otherwise you need to prefix the variable with the name of the task in which it was set, like: $(myTask.SAUCE)).
I am trying to paste some code from MS Docs into PowerShell, the code is for a variable, but when I paste it and hit enter, nothing happens.
Here's the code for the variable:
$site_script = #'
{
"$schema": "schema.json",
"actions": [
{
"verb": "createSPList",
"listName": "Customer Tracking",
"templateType": 100,
"subactions": [
{
"verb": "SetDescription",
"description": "List of Customers and Orders"
},
{
"verb": "addSPField",
"fieldType": "Text",
"displayName": "Customer Name",
"isRequired": false,
"addToDefaultView": true
},
{
"verb": "addSPField",
"fieldType": "Number",
"displayName": "Requisition Total",
"addToDefaultView": true,
"isRequired": true
},
{
"verb": "addSPField",
"fieldType": "User",
"displayName": "Contact",
"addToDefaultView": true,
"isRequired": true
},
{
"verb": "addSPField",
"fieldType": "Note",
"displayName": "Meeting Notes",
"isRequired": false
}
]
}
],
"bindata": { },
"version": 1
}
'#
However, when I paste this and hit enter, nothing happens, and the pointer just goes to a new line that looks like this >>, below is a screenshot:
Is there something I need to do? (Still new to PowerShell)
The error in your Code post is that the ending of your final line includes a space.
$Test = #'
Stuff...
'# #This is wrong as there is a space before '#
$Test = #'
Stuff...
'# #This is correct
I am trying to set up a Cloud Formation Template to create a Cloudwatch-Dashboard.
In this context I want to use the Pseudo Variable to ascertain the Region.
If I simply use the Pseudo Variable AWS::Regionthe code doesnt seem to work:
AutoscalingDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: AutoscalingDashboard
DashboardBody: '
{
"widgets":[
{
"type":"metric",
"x":0,
"y":0,
"width":12,
"height":6,
"properties":{
"metrics":[
[ "AWS/ECS", "MemoryUtilization", "ServiceName", "invoice_web", "ClusterName", "InvoicegenappCluster" ],
[ "...", "invoice_data", ".", "." ],
[ "...", "invoice_generator", ".", "." ]
],
"region": "AWS::Region",
"period": 300,
"view": "timeSeries",
"title":"ECS MemoryUtilization",
"stacked": false
}
How can I use the Pseudo Variable AWS::Region or a RefFunction to keep the variables dynamically?
Merci A
In your example, the DashboardBody is a string, therefore AWS::Region will not get replaced.
You'll probably be better by adding the Fn::Sub function, like:
AutoscalingDashboard:
Type: 'AWS::CloudWatch::Dashboard'
Properties:
DashboardName: 'AutoscalingDashboard'
DashboardBody: !Sub >-
{
"widgets":[
{
"type":"metric",
"x":0,
"y":0,
"width":12,
"height":6,
"properties":{
"metrics":[
[ "AWS/ECS", "MemoryUtilization", "ServiceName", "invoice_web", "ClusterName", "InvoicegenappCluster" ],
[ "...", "invoice_data", ".", "." ],
[ "...", "invoice_generator", ".", "." ]
],
"region": "${AWS::Region}",
"period": 300,
"view": "timeSeries",
"title":"ECS MemoryUtilization",
"stacked": false
}
}]
}
Notice the ${} around the region, and also the YAML block string >-.