[BUG] Upgrade to 3006.9 breaks PowerShell cmd.run/shell commands
Description After upgrading from version 2006.8 to 3006.9 running cmd.run or cmd.shell with PowerShell on Windows servers will result in errors.
Setup Minions are running on Windows 2016, 2019 and 2022 servers.
- [X] on-prem machine
- [X] VM (Virtualbox, KVM, etc. please specify)
- [X] onedir packaging
Steps to Reproduce the behavior This is one of the commands run that now error:
salt * cmd.shell '(Get-Date(Get-Date).ToUniversalTime() -UFormat %s)' shell=PowerShell
Here is the error from a minion running version 3006.9:
& : The term '1737567164.15532' 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:3
+ & (Get-Date(Get-Date).ToUniversalTime() -UFormat %s)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (1737567164.15532:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Expected Behavior On minions running with version 3006.8 the same command will return a number:
1737568937.15566
Versions Report Master:
Salt Version:
Salt: 3006.9
Python Version:
Python: 3.10.14 (main, Jun 26 2024, 11:44:37) [GCC 11.2.0]
Dependency Versions:
cffi: 1.14.6
cherrypy: unknown
cryptography: 42.0.5
dateutil: 2.8.1
docker-py: Not Installed
gitdb: Not Installed
gitpython: Not Installed
Jinja2: 3.1.4
libgit2: 1.3.0
looseversion: 1.0.2
M2Crypto: Not Installed
Mako: Not Installed
msgpack: 1.0.2
msgpack-pure: Not Installed
mysql-python: Not Installed
packaging: 22.0
pycparser: 2.21
pycrypto: Not Installed
pycryptodome: 3.19.1
pygit2: 1.7.1
python-gnupg: 0.4.8
PyYAML: 6.0.1
PyZMQ: 23.2.0
relenv: 0.17.0
smmap: Not Installed
timelib: 0.2.4
Tornado: 4.5.3
ZMQ: 4.3.4
System Versions:
dist: rhel 9.5 Plow
locale: utf-8
machine: x86_64
release: 5.14.0-503.15.1.el9_5.x86_64
system: Linux
version: Red Hat Enterprise Linux 9.5 Plow
Versions Report Minion:
Salt Version:
Salt: 3006.9
Python Version:
Python: 3.10.14 (heads/main:9f7d197, Jun 26 2024, 11:42:40) [MSC v.1940 64 bit (AMD64)]
Dependency Versions:
cffi: 1.14.6
cherrypy: 18.6.1
cryptography: 42.0.5
dateutil: 2.8.1
docker-py: Not Installed
gitdb: 4.0.7
gitpython: Not Installed
Jinja2: 3.1.4
libgit2: Not Installed
looseversion: 1.0.2
M2Crypto: Not Installed
Mako: Not Installed
msgpack: 1.0.2
msgpack-pure: Not Installed
mysql-python: Not Installed
packaging: 22.0
pycparser: 2.21
pycrypto: Not Installed
pycryptodome: 3.19.1
pygit2: Not Installed
python-gnupg: 0.4.8
PyYAML: 6.0.1
PyZMQ: 25.0.2
relenv: 0.17.0
smmap: 4.0.0
timelib: 0.2.4
Tornado: 4.5.3
ZMQ: 4.3.4
System Versions:
dist:
locale: utf-8
machine: AMD64
release: 2022Server
system: Windows
version: 2022Server 10.0.20348 SP0 Multiprocessor Free
Hi there! Welcome to the Salt Community! Thank you for making your first contribution. We have a lengthy process for issues and PRs. Someone from the Core Team will follow up as soon as possible. In the meantime, here’s some information that may help as you continue your Salt journey. Please be sure to review our Code of Conduct. Also, check out some of our community resources including:
- Community Wiki
- Salt’s Contributor Guide
- Join our Community Slack
- IRC on LiberaChat
- Salt Project YouTube channel
- Salt Project Twitch channel
There are lots of ways to get involved in our community. Every month, there are around a dozen opportunities to meet with other contributors and the Salt Core team and collaborate in real time. The best way to keep track is by subscribing to the Salt Community Events Calendar. If you have additional questions, email us at [email protected]. We’re glad you’ve joined our community and look forward to doing awesome things with you!
Also running into this to after moving to 3006.10 from minions with 3006.2 to 3006.6
Appears to stem from PR #66447 where the "&" is prepended to the command passed to powershell -- there's been additional PRs after that to add some exceptions to not prepend the "&" on some things, but it's a pretty limited list.
@twangboy - Isn't the "&" operator primarily needed if you're running a code block (something wrapped in {}) or an script file (which seemed to be the initial problem in #61166)/EXE? Would it be easier to only prepend for those cases versus trying to manage all the possible exceptions? Maybe it is a similar scale problem either way and there are just as many times you'd want to prepend the "&" above and beyond those instances.
Playing with this patch in our environment, but don't know if it breaks how someone else is doing something. "Works for us." This basically checks if the cmd is a script block (starts with '{') or a path (i.e. starting with a drive letter), but might need to handle non-qualified paths and UNC paths as well...
--- /tmp/cmdmod.py.3006.10 2025-06-04 09:34:29.132338638 -0500
+++ /tmp/cmdmod.py.3006.10.mine 2025-06-04 11:11:01.769053856 -0500
@@ -294,16 +294,12 @@
if isinstance(cmd, list):
cmd = " ".join(cmd)
- # Commands that are a specific keyword behave differently. They fail if
- # you add a "&" to the front. Add those here as we find them:
- keywords = ["$", "&", ".", "Configuration", "try"]
-
- for keyword in keywords:
- if cmd.lower().startswith(keyword.lower()):
- new_cmd.extend(["-Command", f"{cmd.strip()}"])
- break
- else:
+ if re.match(r'["\']{0,1}[a-zA-Z]{1}:', cmd.strip()):
+ new_cmd.extend(["-Command", f"& {cmd.strip()}"])
+ elif re.match(r'\{', cmd.strip()):
new_cmd.extend(["-Command", f"& {cmd.strip()}"])
+ else:
+ new_cmd.extend(["-Command", f"{cmd.strip()}"])
log.debug(new_cmd)
return new_cmd
Looking at this now... As a workaround you can add "Write-Host" to the front of your command. You can also drop the parenthesis from the entire command.
If exceptions are being managed, "if" is another one (also do and while). We use a lot of if powershell statements, in requisites or just directly via the cmd module:
$salt 'node' cmd.run_all 'if (1 -eq 1) { exit 0 } else { exit 1}' shell=powershell
node:
----------
pid:
5068
retcode:
1
stderr:
& : The term 'if' 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:3
+ & if (1 -eq 1) { exit 0 } else { exit 1}
+ ~~
+ CategoryInfo : ObjectNotFound: (if:String) [], CommandNotFoundE
xception
+ FullyQualifiedErrorId : CommandNotFoundException
stdout:
@lomeroe Thanks. I added those and a few more to that list.
I think this has been addressed by #68056
Sorry for the slow response on this. Had to find a window I could test. This is now working as expected. I upgraded to 3006.14 Thank for the great work!