Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
lorengordon opened this issue Feb 18, 2020 · 4 comments · Fixed by #56197
Closed

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

lorengordon opened this issue Feb 18, 2020 · 4 comments · Fixed by #56197
Assignees
Labels
fixed-pls-verify fix is linked, bug author to confirm fix

Comments

@lorengordon
Copy link
Contributor

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
@lorengordon
Copy link
Contributor Author

A possible workaround would be to use cmd.run and call the script and args directly in the name argument, but for that we would need to know the full path to the script. Any ideas how to get that?

i.e. this works, but how to get c:/salt/srv/salt/foo/foo.ps1 without hardcoding it?

run foo.ps1:
  cmd.run:
    - name: >-
        c:/salt/srv/salt/foo/foo.ps1
        -Password (ConvertTo-SecureString -String "LifeIsGood?" -AsPlainText -Force)
    - shell: powershell
C:\WINDOWS\system32> C:\salt\salt-call.bat state.sls foo
local:
----------
          ID: run foo.ps1
    Function: cmd.run
        Name: c:/salt/srv/salt/foo/foo.ps1 -Password (ConvertTo-SecureString -String "LifeIsGood?" -AsPlainText -Force)
      Result: True
     Comment: Command "c:/salt/srv/salt/foo/foo.ps1 -Password (ConvertTo-SecureString -String "LifeIsGood?" -AsPlainText -Force)" run
     Started: 14:31:01.277000
    Duration: 305.0 ms
     Changes:
              ----------
              pid:
                  23992
              retcode:
                  0
              stderr:
              stdout:
                  01000000d08c9ddf0115d1118c7a00c04fc297eb01000000c99c6609ffef3d46a21978eada52116100000000020000000000106600000001000020000000d244a9db61f7623b6f4753db71ef337e6522ee21e4fc7222a276f25fa4de3879000000000e8000000002000020000000924cb5750608a28828f0dc9962ebb36e758044e44f4b7e64942257f1287fbb13200000000431664ec8c6073a1990ed32ea9aab9e2273d945da245914d7d73a1f7a14c751400000006fca57462fcfa3bacc7f6764e9a8e5f40bba671f6beecb6e44f87061954cb3ef4abcd3ad3113b12e76e87c3a294d529b25cda2a281b0fc801660da9d32047a0c

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

@lorengordon
Copy link
Contributor Author

Looking through the history, I didn't see any conversation about the usage of -File with cmd.script... #5620

@dwoz
Copy link
Contributor

dwoz commented Feb 25, 2020

@twangboy Can you verify this please?

@twangboy
Copy link
Contributor

Verified

@twangboy twangboy self-assigned this Mar 9, 2020
@twangboy twangboy added the fixed-pls-verify fix is linked, bug author to confirm fix label Mar 9, 2020
@twangboy twangboy closed this as completed Mar 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed-pls-verify fix is linked, bug author to confirm fix
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants