How do I invoke a command using a variable in powershell? - powershell

I want to invoke the shutdown.exe executable in powershell and it is located on C:\WINDOWS\System32\shutdown.exe.
Since we already got the C:\WINDOWS in the variable $env:windir I want to just use it and concatenate the rest of the path into the command. I was trying this:
PS C:\Users\shina> .\$env:windir\System32\shutdown.exe -s
But I got the following error:
.\$env:windir\System32\shutdown.exe: The term '.\$env:windir\System32\shutdown.exe' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
How can I accomplish this?

You can use:
& $env:windir\System32\shutdown.exe -s
Or
. $env:windir\System32\shutdown.exe -s
(note the space).
& is the call operator. You can read more about it here:
Runs a command, script, or script block. The call operator, also known as the "invocation operator", lets you run commands that are stored in variables and represented by strings or script blocks.
. is the dot sourcing operator. You can read more about it here:
Runs a script in the current scope so that any functions, aliases, and variables that the script creates are added to the current scope, overriding existing ones.
The dot sourcing operator is followed by a space. Use the space to distinguish the dot from the dot (.) symbol that represents the current directory.

Related

How to use a GitLab variable to represent the directory to a command in PowerShell

I am writing a PowerShell script for a GitLab CICD pipeline that will deploy a file to our TEST box via FTP. This works by using a command to execute an FTP client (winSCP.exe) with a text file as input.
The basic code works, however I decided to replace the hardcoded values and paths with GitLab variables for greater security and to simplify changes. Most of the variable additions worked, but using a variable to replace the path to the FTP client failed - see below:
./$FTPCLIENTDIRECTORY : The term './$FTPCLIENTDIRECTORY' 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.
Right now this section of code works:
'./Resources/WinSCP.exe /log="$LOGFILEDIRECTORY" /ini=nul /script="$SCRIPTDIRECTORY" /parameter $FTPUSERNAME $FTPPASSWORD $FTPCERTIFICATE $FTPFILE'
I am trying to get something more like:
'./$FTPCLIENTDIRECTORY /log="$LOGFILEDIRECTORY" /ini=nul /script="$SCRIPTDIRECTORY" /parameter $FTPUSERNAME $FTPPASSWORD $FTPCERTIFICATE $FTPFILE'
I'm guessing that the ./ here operates as some kind of escape sequence that prevents YAML from recognizing the variable, however nothing none of the YAML or PowerShell escape characters I've used to escape-the-escape characters have worked.
Do you have any insight into why this is happening and or what a solution might be?

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 }

Running a script in bash

I have a script in one of my application folders.Usually I just cd into that locatin in Unix box and run the script e.g.
UNIX> cd My\Folder\
My\Folder> MyScript
This prints the required result.
I am not sure how do I do this in Bash script.I have done the following
#!/bin/bash
mydir=My\Folder\
cd $mydir
echo $(pwd)
This basically puts me in the right folder to run the required script . But I am not sure how to run the script in the code?
If you can call MyScript (as opposed to ./MyScript), obviously the current directory (".") is part of your PATH. (Which, by the way, isn't a good idea.)
That means you can call MyScript in your script just like that:
#!/bin/bash
mydir=My/Folder/
cd $mydir
echo $(pwd)
MyScript
As I said, ./MyScript would be better (not as ambiguous). See Michael Wild's comment about directory separators.
Generally speaking, Bash considers everything that does not resolve to a builtin keyword (like if, while, do etc.) as a call to an executable or script (*) located somewhere in your PATH. It will check each directory in the PATH, in turn, for a so-named executable / script, and execute the first one it finds (which might or might not be the MyScript you are intending to run). That's why specifying that you mean the very MyScript in this directory (./) is the better choice.
(*): Unless, of course, there is a function of that name defined.
#!/bin/bash
mydir=My/Folder/
cd $mydir
echo $(pwd)
MyScript
I would rather put the name in quotes. This makes it easier to read and save against mistakes.
#!/bin/bash
mydir="My Folder"
cd "$mydir"
echo $(pwd)
./MyScript
Your nickname says it all ;-)
When a command is entered at the prompt that doesn't contain a /, Bash first checks whether it is a alias or a function. Then it checks whether it is a built-in command, and only then it starts searching on the PATH. This is a shell variable that contains a list of directories to search for commands. It appears that in your case . (i.e. the current directory) is in the PATH, which is generally considered to be a pretty bad idea.
If the command contains a /, no look-up in the PATH is performed. Instead an exact match is required. If starting with a / it is an absolute path, and the file must exist. Otherwise it is a relative path, and the file must exist relative to the current working directory.
So, you have two acceptable options:
Put your script in some directory that is on your PATH. Alternatively, add the directory containing the script to the PATH variable.
Use an absolute or relative path to invoke your script.

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" ....

finding a files path in the command line

I am doing a batch scripting assignment where I have to call one script from inside another. I need the script to run the second script no matter where my lecturer saves these scripts. How would I do this. Is there some way to find the path of script inside the script and use that to execute the file. Any help would be great. I think I need to use %'s but i'm not sure.
The name of the script is Hello World.bat.
How would I copy Hello World.bat to the C:\ if I don't know which directory the lecturer has placed it in. what command/s would I use so that the copy would work regardless of the scripts location.
I don't see the "DOS" tag, but I'll assume that it is for now. If you want the entire path, you can get it by doing this:
echo %cd%
If you want just the last folder, this works (inside a .bat file):
for %%* in (.) do #echo %%~n*
Note that from the command line, the above command will work with single %'s:
for %* in (.) do #echo %~n*
If the script you are executing is calling other scripts in the SAME folder location, you can prefix the path statement with "%~dp0" or "%~dps0" but do not put a backslash between that and the name of the script you are calling. In other words, if script1.bat is calling script2.bat in the same folder, the statement in script1.bat would refer to "%~dp0script2.bat"
sorry about batch files, am not familiar, but in nix shell, there is the locate command which can return the path of the file , if you know the filename exactly and the name is unique.
like
name=$(locate filname)