salt
salt copied to clipboard
[BUG] failed to execute powershell script using "cmd.script" with "runas" parameter
Description Failed to execute powershell script using "cmd.script" with "runas" parameter. Step fails with error:
^C:\ProgramData\Salt Project\Salt\var\cache\salt\minion\tmpg02cql8w\__salt.tmp.j_yi8_ho.ps1^ : The term
'^C:\ProgramData\Salt Project\Salt\var\cache\salt\minion\tmpg02cql8w\__salt.tmp.j_yi8_ho.ps1^' is not recognized as
the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:1 char:1
+ ^"C:\ProgramData\Salt Project\Salt\var\cache\salt\minion\tmpg02cql8w\ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (^C:\ProgramData...p.j_yi8_ho.ps1^:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Setup Issue is reproducible locally on salt-minion and through salt-master.
OS: Windows Server 2019 PowerShell version: 5.1.17763.2183 Salt: 3004
Steps to Reproduce the behavior Execute the following sls file:
C:\\ProgramData\\test-script.ps1:
file.managed:
- contents:
- Write-Host "Hello World"
create_user:
user.present:
- name: testuser
- password: 'MySuper!Str0ngPassw0rd'
run_script:
cmd.script:
- source: "C:\\ProgramData\\test-script.ps1"
- shell: powershell
- runas: testuser
- password: 'MySuper!Str0ngPassw0rd'
delete_user:
user.absent:
- name: testuser
- purge: True
Note: user creation step is not mandatory if you already have some testing user to use for "runas".
Expected behavior Step "run_script" should finish successfully with "Hello World" stdout message
Debug log: salt-debug-log.txt Salt output: salt-output.txt
Versions Report
salt --versions-report
(Provided by running salt --versions-report. Please also mention any differences in master/minion versions.)Salt Version:
Salt: 3004
Dependency Versions:
cffi: 1.14.6
cherrypy: 18.6.1
dateutil: 2.8.1
docker-py: Not Installed
gitdb: 4.0.7
gitpython: Not Installed
Jinja2: 2.10.1
libgit2: Not Installed
M2Crypto: Not Installed
Mako: 1.1.4
msgpack: 0.6.2
msgpack-pure: Not Installed
mysql-python: Not Installed
pycparser: 2.20
pycrypto: Not Installed
pycryptodome: 3.10.1
pygit2: Not Installed
Python: 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)]
python-gnupg: 0.4.7
PyYAML: 5.4.1
PyZMQ: 19.0.0
smmap: 4.0.0
timelib: 0.2.4
Tornado: 4.5.3
ZMQ: 4.3.2
System Versions:
dist:
locale: cp1252
machine: AMD64
release: 2019Server
system: Windows
version: 2019Server 10.0.17763 SP0 Multiprocessor Free
Additional context cmd.script works fine if you don't use "runas" parameter.
I am having the same issue... happy to help fix the bug if I can! Is there anything I can do to help?
@ovybach I have figured out the issue and submitted a PR for the maintainers consideration. As a workaround, you can edit the configuration file on your minions and set the cachedir
to a directory that doesn't have a space in it, and it should fix the problem.
Apparently, Salt changed the default rootdir with version 3004 to C:/ProgramData/Salt Project, which includes a whitespace and the Powershell calls later are not using the appropriate quotes. It's actually a really bad implementation. Not sure how this could pass the QA, it's also not mentioned in the documentation. And the support told us to wait for a fix in some future release.
There is actually a much simpler solution: just use the MSI installer and pass the installdir and rootdir as parameters. The installer will take care of the rest and use the same directories that older versions were using (C:/salt). No manual editing of config files required.
Here's a sample call from my install script, works perfectly fine with 3004.2: Start-Process "msiexec.exe" -ArgumentList "/i c:\Salt-Minion-3004.2-1-Py3-AMD64.msi /quiet INSTALLDIR=c:\salt ROOTDIR=c:\salt MASTER=$mastername MINION_ID=$minionname" -Wait
To the Salt devs: Please consider to make C:\salt the default again. It worked for years without any problems and there is no reason to force a move to ProgramData ;-)
This is how I made it work on my 3004.2 minion. Unfortunately, haven't set up environment to test all possible scenarios.
--- cmdmod.py 2023-10-10 10:22:08.481207377 +0200
+++ cmdmod_patched.py 2023-10-16 23:21:12.712247574 +0200
@@ -367,8 +367,11 @@
# The last item in the list [-1] is the current method.
# The third item[2] in each tuple is the name of that method.
if stack[-2][2] == "script":
- cmd = '"{}" -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command {}'.format(
- shell, cmd
+ runas_cmd_prep = ""
+ if runas:
+ runas_cmd_prep = "&"
+ cmd = '"{}" -NonInteractive -NoProfile -ExecutionPolicy Bypass -Command {}{}'.format(
+ shell, runas_cmd_prep, cmd
)
elif encoded_cmd:
cmd = '"{}" -NonInteractive -NoProfile -EncodedCommand {}'.format(
@@ -2858,7 +2861,7 @@
os.chmod(path, 320)
os.chown(path, __salt__["file.user_to_uid"](runas), -1)
- if salt.utils.platform.is_windows() and shell.lower() != "powershell":
+ if salt.utils.platform.is_windows():
cmd_path = _cmd_quote(path, escape=False)
else:
cmd_path = _cmd_quote(path)