Execute command with arguments and a pipe - powershell

I'm trying to execute the command below in a PowerShell script
C:\PATH TO GPG\gpg.exe --output OUTPUTFILE.csv --batch --passphrase-fd 0 --decrypt C:\PATH TO INPUT\INPUTFILE.txt < C:\PATH TO PASS\Passphrase.txt
When I assign various sections of the command to variables and then combine them in a command varible and try and execute it as follows:
$decryptCommand = "${gpg} --output ${dateStamp}.csv --batch --passphrase-fd 0 --decrypt ${fileName} < ${passphraseFile}"
&$decryptCommand
I receive the following error:
The term 'XXXX' 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.
I have tried to surround various parts of the command in single and double quotes but nothing I've tried seems to work.
Is there something extra I should be doing to execute this command from a PowerShell script?

There are several problems with you script. First, you don't need to surround variable with {}, secon - you have to pass parameters seperately, like this:
&$gpg --output $dateStamp.csv --batch --passphrase-fd 0 --decrypt $fileName < $passphraseFile
The only thing I'm not sure about is < symbol. It might be the case that you will need to escape it with '

Related

Trying to create an alias to include options in powershell

My goal is to have an alias to run a command with -o at the end.
PS C:\Users\XXXX> vlab -o <various different arguments>
I have tried to setup an alias, but Set-Alias recognizes -o as a parameter Option, and
placing it in single or double quotes fails
> set-alias vlab 'vlab -o'
> vlab
vlab : The term 'vlab -o' is not recognized as the name of a cmdlet, function, script file, or operable program.
also setup a profile.ps1 with a function, but this just hangs when I run it.
Function VlabSpeed {
vlab -o
}
Set-Alias vlab VlabSpeed
Is it possible to set an alias like this?
if so, how?
Thanks
To recap:
PowerShell aliases can only map a name to another command name or executable file path - unlike in, say, Bash, defining arguments as part of the mapping is not supported.
To incorporate arguments, you indeed need a function rather than an alias:
Inside that function, you can use #args to pass any arguments through to another command, as Santiago Squarzon points out.
There is no need for both an alias and a function - just name your function directly as the short name you desire.
If your short (function) name is the same as the file name of the external program that it wraps, you need to disambiguate the two to avoid infinite recursion:
On Windows:
Use the external program's filename extension, typically .exe:
function vlab { vlab.exe -o #args }
On Unix-like platforms:
Given that executables there (typically) have no filename extension, use the full path to disambiguate:
function vlab { /path/to/vlab -o #args }

Execute a bat file with a variable name in the path

I am having a problem executing a powershell script where I want to point to different versions of a bat file based on some arguments
Hard coding the path as follows works with no issues:
& 'C:\Program Files\MATLAB\R2022a\bin\mcc.bat' -W $command -T link:exe ...
but replacing a folder name with a variable causes it to fail:
$Matlab_version = "R2022a"
& 'C:\Program Files\MATLAB\$Matlab_version\bin\mcc.bat' -W $command -T link:exe
with the following output:
& : The term 'C:\Program Files\MATLAB\%$Matlab_version%\bin\mcc.bat' 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
+ & 'C:\Program Files\MATLAB\%$Matlab_version%\bin\mcc.bat' -W $comman ...
I've tried even creating a variable with the path name
$mcc_loc = & 'C:\Program Files\MATLAB\$Matlab_version\bin\mcc.bat'
Write-Host $mcc_loc
which produces a string with the correct path. Any help is greatly appreciated. My dumb solution is to have an if statement for each $Matlab_version and hard code it in there but I'm sure there has to be a more elegant solution
It's because you are using single quotation marks.
variables will not be interpreted within single marks, everything will be taken as a literal string.
use double quotes instead when passing in variables mid string.
example:
You need to change the single quote ' to double quote "
Double-quoted strings
A string enclosed in double quotation marks is an expandable string. Variable names preceded by a dollar sign ($) are replaced with the variable's value before the string is passed to the command for processing.
$Matlab_version = "R2022a"
& "C:\Program Files\MATLAB\$Matlab_version\bin\mcc.bat" -W $command -T link:exe
See about_Quoting_Rules

PowerShell command only works without spaces between arguments

I try certain source codes using PowerShell to extract an password protected archive using 7zip:
This command doesn' work (7zip is an alias for $7zipPath):
& 7zip x "$zipFile" -o "$output" -p $zipFilePassword
I get the this error:
Command Line Error:
Too short switch:
But when I remove the spaces between the variables -o and -p, the archive can be extracted. This behaviour confuses me with other command line tools like git etc.? Why is it so?
The behavior is specific to 7-Zip (7z.exe) and applies to whatever program (shell) you invoke it from:
Deviating from widely used conventions observed by CLIs such as git, 7z requires that even switches (options) that have mandatory arguments, such as -o and -p, have the argument directly attached to the switch name - no spaces are allowed:
& 7zip x $zipFile -o"$output" -p"$zipFilePassword"
Note that you normally need not enclose variable references in PowerShell in "..." (note how $zipFile isn't), even if they contain spaces. However, in order to attach them directly to switch names, you do.
Alternatively, you could enclose the entire token - switch name and argument - in double quotes:
& 7zip x $zipFile "-o$output" "-p$zipFilePassword"

Sending a pipe as an argument to an external program in Powershell?

I keep getting the following error when running a command to look for the most recently modified directory in my path: remotely from PowerShell:
head: The term 'head' 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: 95
+ ... d /somedir ; (lastmod=$(ls -tda -- */ | head -n 1); ....
I'm running code something along the lines of the following:
& plink "bob#server" "cd /somedir ; (lastmod=$(ls -tda -- */ | head -n 1); ls -la $lastmod)"
You've encapsulated your commands in double-quotes so the $ signs are being expanded by PowerShell. If you use single quotes this won't happen.
Just to add on to Bruce's answer, you could also escape the special character from your double-quoted string using the grave accent (`), which is the escape character in powershell.
& plink "bob#server" "cd /somedir ; (lastmod=$(ls -tda -- */ `| head -n 1); ls -la $lastmod)"
This means that if you did need any variables inside of your string, you could still utilize special characters.

How can I execute an external program with parameters in PowerShell?

I have read this answer stackoverflow answer and it get's me there half way. Here is what I need to do.
Execute this command:
"c:\myexe.exe <c:\Users\Me\myanswerfile.txt"
If I run that straight from within my powershell script
&'c:\myexe.exe <c:\Users\Me\myanswerfile.txt'
I get this error:
The term 'C:\myexe.exe <c:\Users\Me\myanswerfile.txt' 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, verif that the path is correct and try again.
Now I have tried several variations of this including placing the original command in a variable called $cmd and then passing the
If I append the '<' to the $cmd variable the command fails with a similar error as the first one.
I'm stumped. Any suggestions?
If you want to run a program, just type its name and parameters:
notepad.exe C:\devmy\hi.txt
If you want to run an exe and redirect stdin to it which your example seems to be an attempt of, use:
Get-Content c:devmy\hi.txt | yourexe.exe
If you need to specify the full path to the program then you need to use ampersand and quotes otherwise powershell thinks you are defining a plain string:
&"C:\Program Files (x86)\Notepad++\notepad++.exe"
Simply use & operator
& "Program\path\program.exe" "arg1" "arg2" ....