Passing a variable to a powershell script via command line - powershell

I am new to powershell, and trying to teach myself the basics. I need to write a ps script to parse a file, which has not been too difficult.
Now I want to change it to pass a variable to the script. that variable will be the parsing string. Now, the variable will always be 1 word, and not a set of words or multiple words.
This seems uber simple yet is posing a problem for me. Here is my simple code:
$a = Read-Host
Write-Host $a
When I run the script from my command line the variable passing doesn't work:
.\test.ps1 hello
.\test.ps1 "hello"
.\test.ps1 -a "hello"
.\test.ps1 -a hello
.\test.ps1 -File "hello"
As you can see, I have tried many methos with no success, of the script taking the value an outputting it.
The script does run, and waits for me to type a value, and when I do, it echos that value.
I just want it to output my passed in value, what minuscule thing am I missing?
Thank you.

Make this in your test.ps1, at the first line
param(
[string]$a
)
Write-Host $a
Then you can call it with
./Test.ps1 "Here is your text"
Found here (English)

Here's a good tutorial on Powershell params:
PowerShell ABC's - P is for Parameters
Basically, you should use a param statement on the first line of the script
param([type]$p1 = , [type]$p2 = , ...)
or use the $args built-in variable, which is auto-populated with all of the args.

Declare the parameter in test.ps1:
Param(
[Parameter(Mandatory=$True,Position=1)]
[string]$input_dir,
[Parameter(Mandatory=$True)]
[string]$output_dir,
[switch]$force = $false
)
Run the script from Run OR Windows Task Scheduler:
powershell.exe -command "& C:\FTP_DATA\test.ps1 -input_dir C:\FTP_DATA\IN -output_dir C:\FTP_DATA\OUT"
or,
powershell.exe -command "& 'C:\FTP DATA\test.ps1' -input_dir 'C:\FTP DATA\IN' -output_dir 'C:\FTP DATA\OUT'"

Passed parameter like below,
Param([parameter(Mandatory=$true,
HelpMessage="Enter name and key values")]
$Name,
$Key)
.\script_name.ps1 -Name name -Key key

Using param to name the parameters allows you to ignore the order of the parameters:
ParamEx.ps1
# Show how to handle command line parameters in Windows PowerShell
param(
[string]$FileName,
[string]$Bogus
)
write-output 'This is param FileName:'+$FileName
write-output 'This is param Bogus:'+$Bogus
ParaEx.bat
rem Notice that named params mean the order of params can be ignored
powershell -File .\ParamEx.ps1 -Bogus FooBar -FileName "c:\windows\notepad.exe"

Related

Is there a dynamic variable for passed arguments in powershell?

In batch, passed arguments can be used with %1, and onward counting.
Lets say I have the following "batch.bat" script:
# echo off
echo %1
pause>nul
If i call this from cmd like: call batch.bat hello it would output "hello" in the console.
Is there any variable in ps which does the same thing?
EDIT
I've found the folliwing, but it seems kind of unnatural.
$CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
Exit
}
Is there something more elegant perhaps?
PowerShell has an automatic variable $args that stores all arguments passed to a script (unless parameters were defined for the script). The individual arguments can be accessed by index ($args[0] for the first argument, $args[1] for the second, etc.).
However, in general it's advisable to define parameters to control what arguments a script should accept, e.g.
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$First,
[Parameter(Mandatory=$false)]
[integer]$Second = 42
)
There are numerous advantages to this, including (but not limited to):
arguments are parsed automatically and the values are stored in the respective variables
scripts automatically prompt for mandatory parameters
scripts throw an error if incorrect arguments are passed
you can define default values for optional parameters
you can have your script or function accept pipeline input
you can validate parameter values
you can use comment-based help for documenting the parameters and their usage

Calling a ps1 from another ps1

I am calling a ps1 script from another ps1, which woks fine. Now I want to pass the arguments to a child ps1 from parent ps1.
For e.g.
1. master.ps1 & client.ps1 are the two scripts.
2. client.ps1 takes two arguments, which i want to pass to it through master.ps1.
Code for the master script:
Param(
[Parameter(Mandatory=$True,Position=4)]
[string]$clientid,
[Parameter(Mandatory=$True,Position=4)]
[string]$clientname
)
Invoke-Expression "$bpath\client.ps1" "$clientid" "$clientname"
Error:
Invoke-Expression : A positional parameter cannot be found that accepts argument
Any suggestions?
You can test :
& .\YourScript.ps1 Arg1 Arg2
But it exists other solutions if you want to keep Invoke-Expression you can use :
Invoke-Expression -Command ".\YourScript.ps1 Arg1 Arg2"
Parameters can be passed as array totally in a single $var or if you are passing very few params then you should prefix it with the param name. Try the below one it should work
Invoke-Expression "$bpath\client.ps1" -clientid $clientid -clientname $clientname
or you can directly pass the $var, if you prefix the "$var" it becomes a string rather than a param
Invoke-Expression "$bpath\client.ps1" $clientid $clientname

How do I pass second parameter from CMD (%2) into a PowerShell variable

I have a file called test.bat.
It contains a call to a PowerShell script (Process.ps1) as follows:
Powershell.exe -File %1
where %1 is the name of the PowerShell file I would pass on the command line.
So essentially, it looks like this on the command line:
e:> test.bat Process.ps1
Right now the script runs as it should. However, I need to pass a second argument (%2) in the batch file (test.bat) so it would look like this:
Powershell.exe -File %1 %2
%1 is Process.ps1
%2 will be some cube name (i.e. CUBE1)
So on CMD it would look like this eventually:
e:> test.bat Process.ps1 CUBE1
Now, how can I pass that second argument (CUBE1) into a variable ($CUBE) declared in the PowerShell script (Process.ps1)?
I researched around the forums, but I can't find an example like my own case.
This may be something very simple I'm missing out on, but I am new to PowerShell/batch scripting so I can't quite put my finger on the answer.
There are two ways. The first is the use of the Parameter declarations:
Param(
[Parameter(mandatory)]
[String]
$first,
[Parameter(mandatory)]
[String]
$second
)
Write-Output "First argument: " $first
Write-Output "First argument: " $second
The second is the built-in $args variable:
Write-Output "First argument: " $args[0]
Write-Output "Second argument: " $args[1]

PowerShell script does not receive arguments no matter what

Trying to pass a single command line argument to a powershell script on Windows 7, but the script does not seem to recognize any arguments. It blasts through the first lines below
foreach($arg in $args)
{
Write-Host "Arg: $arg";
}
without outputting anything that I use on the command line and fails due to $args[0] being empty. However the rest of my script works if I instead hardcode the value of the variable I am trying to assign from the command line (it simply opens that file and does something).
I was inspired by this answer Passing a variable to a powershell script via command line specifically by the link in the accepted answer, and tried using param block but that did not print out anything as well
param(
[string]$fileName
)
Write-Host "Filename: [ $fileName ]";
when invoked like script.ps1 -filename SampleFile.txt
When I simply copy/paste the first script from the link into a new script:
Write-Host "Num Args:" $args.Length;
foreach ($arg in $args)
{
Write-Host "Arg: $arg";
}
and call it as 1.ps1 1 2 3 its output is only Num Args: 0.
What am I doing wrong?
PS: If it matters, here is version information
PS Z:\> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
2 0 -1 -1
I don't think it has anything to do with file linking, or registry hacking! :)
When running the example code, I also get no return when using your code. But when you make the parameter MANDATORY, it starts to display the arguments. Just need to format the PARAM Correctly, as in:
Param( [Parameter(Mandatory=$True)]
[string]$argument_one
)
Write-Host "Hello World $argument_one"
There you have it. Now you can call it from CMD as in:
powershell.exe -command "& 'thePSFile.ps1' -$argument_one 'it works now'"
I hope this Helps. I know, resurrected from the dead, but I thought some other people searching could see how they were almost there.
//ark
I have this problem as well. It took a while to recover what I have done previously.
First approach: make sure assoc, ftype and %PATHEXT% are set for powershell:
C:\>assoc .ps1
.ps1=Microsoft.PowerShellScript.1
C:\>ftype Microsoft.PowerShellScript.1
Microsoft.PowerShellScript.1="C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe" -noexit -file %1 %~2
C:\>echo %PATHEXT%
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.py;.pyw;.ps1
But this likely will not work in windows 7 or higher.
Then edit the registry (all cautions apply here)
Edit the registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\0\Command
Set it from
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1"
To
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" %~2
Good luck!

Pass parameter from a batch file to a PowerShell script

In my batch file, I call the PowerShell script like this:
powershell.exe "& "G:\Karan\PowerShell_Scripts\START_DEV.ps1"
Now, I want to pass a string parameter to START_DEV.ps1. Let's say the parameter is w=Dev.
How can I do this?
Let's say you would like to pass the string Dev as a parameter, from your batch file:
powershell -command "G:\Karan\PowerShell_Scripts\START_DEV.ps1 Dev"
put inside your powershell script head:
$w = $args[0] # $w would be set to "Dev"
This if you want to use the built-in variable $args. Otherwise:
powershell -command "G:\Karan\PowerShell_Scripts\START_DEV.ps1 -Environment \"Dev\""
and inside your powershell script head:
param([string]$Environment)
This if you want a named parameter.
You might also be interested in returning the error level:
powershell -command "G:\Karan\PowerShell_Scripts\START_DEV.ps1 Dev; exit $LASTEXITCODE"
The error level will be available inside the batch file as %errorlevel%.
Assuming your script is something like the below snippet and named testargs.ps1
param ([string]$w)
Write-Output $w
You can call this at the commandline as:
PowerShell.Exe -File C:\scripts\testargs.ps1 "Test String"
This will print "Test String" (w/o quotes) at the console. "Test String" becomes the value of $w in the script.
When a script is loaded, any parameters that are passed are automatically loaded into a special variables $args. You can reference that in your script without first declaring it.
As an example, create a file called test.ps1 and simply have the variable $args on a line by itself. Invoking the script like this, generates the following output:
PowerShell.exe -File test.ps1 a b c "Easy as one, two, three"
a
b
c
Easy as one, two, three
As a general recommendation, when invoking a script by calling PowerShell directly I would suggest using the -File option rather than implicitly invoking it with the & - it can make the command line a bit cleaner, particularly if you need to deal with nested quotes.
Add the parameter declaration at the top of ps1 file
test.ps1
param(
# Our preferred encoding
[parameter(Mandatory=$false)]
[ValidateSet("UTF8","Unicode","UTF7","ASCII","UTF32","BigEndianUnicode")]
[string]$Encoding = "UTF8"
)
write ("Encoding : {0}" -f $Encoding)
Result
C:\temp> .\test.ps1 -Encoding ASCII
Encoding : ASCII
The answer from #Emiliano is excellent. You can also pass named parameters like so:
powershell.exe -Command 'G:\Karan\PowerShell_Scripts\START_DEV.ps1' -NamedParam1 "SomeDataA" -NamedParam2 "SomeData2"
Note the parameters are outside the command call, and you'll use:
[parameter(Mandatory=$false)]
[string]$NamedParam1,
[parameter(Mandatory=$false)]
[string]$NamedParam2