Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Windows: Using inline powershell in args with cmd.script and shell: powershell #56195

@lorengordon

Description

@lorengordon

Description of Issue

The way salt invokes powershell seems to make it impossible to pass inline powershell to cmd.script args, to allow for values being built-up in ps objects. I.e. how would you run a script that requires a SecureString or a PSCredential as a parameter?

Setup

Say you have the script foo.ps1:

[CmdLetBinding()]
Param(
  [SecureString] $Password
)

$Password | ConvertFrom-SecureString

And you want to call it with cmd.script:

run foo.ps1:
  cmd.script:
    - name: salt://foo/foo.ps1
    - args: >-
        -Password (ConvertTo-SecureString -String "LifeIsGood?" -AsPlainText -Force)
    - shell: powershell

When you run this state, you get an error:

C:\WINDOWS\system32> C:\salt\salt-call.bat state.sls foo
[ERROR   ] Command 'chcp 437 > nul & Powershell -NonInteractive -NoProfile -ExecutionPolicy Bypass -File c:\users\x\appdata\local\temp\__salt.tmp.bsewzw.ps1 -Password (ConvertTo-SecureString -String "LifeIsGood?" -AsPlainText -Force)' failed with return code: 1
[ERROR   ] stderr: C:\users\x\appdata\local\temp\__salt.tmp.bsewzw.ps1 : Cannot process argument transformation on parameter 'Password'. Cannot convert the "(ConvertTo-SecureString" value of type "System.String" to type "System.Security.SecureString".
    + CategoryInfo          : InvalidData: (:) [__salt.tmp.bsewzw.ps1], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,__salt.tmp.bsewzw.ps1
[ERROR   ] retcode: 1
[ERROR   ] {u'pid': 8060, u'retcode': 1, u'stderr': u'C:\\users\\x\\appdata\\local\\temp\\__salt.tmp.bsewzw.ps1 : Cannot process argument transformation on parameter \'Password\'. Cannot convert the "(ConvertTo-SecureString" value of type "System.String" to type "System.Security.SecureString".\r\n    + CategoryInfo          : InvalidData: (:) [__salt.tmp.bsewzw.ps1], ParentContainsErrorRecordException\r\n    + FullyQualifiedErrorId : ParameterArgumentTransformationError,__salt.tmp.bsewzw.ps1', u'stdout': u''}
local:
----------
          ID: run foo.ps1
    Function: cmd.script
        Name: salt://foo/foo.ps1
      Result: False
     Comment: Command 'salt://foo/foo.ps1' run
     Started: 14:05:43.082000
    Duration: 486.0 ms
     Changes:
              ----------
              pid:
                  8060
              retcode:
                  1
              stderr:
                  C:\users\x\appdata\local\temp\__salt.tmp.bsewzw.ps1 : Cannot process argument transformation on parameter 'Password'. Cannot convert the "(ConvertTo-SecureString" value of type "System.String" to type "System.Security.SecureString".
                      + CategoryInfo          : InvalidData: (:) [__salt.tmp.bsewzw.ps1], ParentContainsErrorRecordException
                      + FullyQualifiedErrorId : ParameterArgumentTransformationError,__salt.tmp.bsewzw.ps1
              stdout:

Summary for local
------------
Succeeded: 0 (changed=1)
Failed:    1
------------
Total states run:     1
Total run time: 486.000 ms

This is because when calling powershell.exe with -File, all the arguments are passed as strings. This means the inline powershell is not executed; it is simply treated exactly as a string.

You can run the command in the cmd shell to repro easily:

C:\WINDOWS\system32>Powershell -NonInteractive -NoProfile -ExecutionPolicy ByPass -File c:\salt\srv\salt\foo\foo.ps1 -Password (ConvertTo-SecureString -String "Foo" -AsPlainText -Force)
C:\salt\srv\salt\foo\foo.ps1 : Cannot process argument transformation on parameter 'Password'. Cannot convert the
"(ConvertTo-SecureString" value of type "System.String" to type "System.Security.SecureString".
    + CategoryInfo          : InvalidData: (:) [foo.ps1], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,foo.ps1

Contrast this with just removing -File in the command, it works!:

C:\WINDOWS\system32>Powershell -NonInteractive -NoProfile -ExecutionPolicy ByPass c:\salt\srv\salt\foo\foo.ps1 -Password (ConvertTo-SecureString -String "Foo" -AsPlainText -Force)
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000c99c6609ffef3d46a21978eada52116100000000020000000000106600000001000020000000de43b7729c577bbc76ccf41faddc58583de943f0d1270046c627dad3a9dc32ed000000000e8000000002000020000000deb7262a68ef59ca2e024f50ab086f78041c4d478406515067c4992ea2ae8be410000000aaafb3f646913c4f22b44a001ec566ce400000004297820393430b401459f1ea1fc38b29b5f12edb066ce54236e7522d7305c09d7db1024cf0b1e7acceb5c22d7fa7099a3e64b04f4f71f5137e9a1c76bb23c7e7

And if I make that change locally in my salt install, just removing -File:

C:\WINDOWS\system32> C:\salt\salt-call.bat state.sls foo
local:
----------
          ID: run foo.ps1
    Function: cmd.script
        Name: salt://foo/foo.ps1
      Result: True
     Comment: Command 'salt://foo/foo.ps1' run
     Started: 14:11:56.808000
    Duration: 419.0 ms
     Changes:
              ----------
              pid:
                  27432
              retcode:
                  0
              stderr:
              stdout:
                  01000000d08c9ddf0115d1118c7a00c04fc297eb01000000c99c6609ffef3d46a21978eada52116100000000020000000000106600000001000020000000dff78a1a2e8b68ee40ac036d3820b5f50464942357ee61ac13ca0d038398f8f4000000000e80000000020000200000005c8e3870ed352549bf07bda75308b29a0dcc142a7fd4ac398111fe734d0b437f20000000838982aa0e2977b5b26d1428fa44b85e00d35254aa0a314ab0b80f94623e69ef400000005bf116d6d2ab8a8e8dd446d4b36658729b1561f8ba45b22630980c8fef5350f93b96520de411d9cb60bb4ee71f31c2fd7a0de7dd24ec7086685d394c6127a403

Summary for local
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time: 419.000 ms

Metadata

Metadata

Assignees

Labels

fixed-pls-verifyfix is linked, bug author to confirm fix

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions