How to run PowerShell script elegant? - powershell

For running ps1 file I should type something like:
powershell "./script.ps1 -t 'Param string'"
But the running of bat-file has much more kindly view:
script 'Param string'
Is it possible to simplify the syntax to run a ps1 file? It should be comfortable for typing from keyboard.

Since you are tagged the question with PowerShell only, I assume you want to call a ps1 from Powershell.
Consider a script printing a message, called message.ps1:
Param
(
$msg
)
Write-Host $msg
The way I used to call it is:
.\message.ps1 -msg "hello"
You can also omit the -msg prefix and just pass the string to print:
.\message.ps1 "hello"

It seems the most easy way to solve my question is calling ps1 script from bat script.
Then the string powershell "./script.ps1 -t 'Param string'"
could be easy represented as script 'Param string'

Related

Powershell write to stdout (no newline)

I need something absolutely simple but apparently totaly impossible. I need to write something to stdout in powershell.
So far I found only write-output but this unfortunately appends linefeed. I tried to somehow "hack" it by getting stdout from .net but I always get host stream which doesnt do what I want.
Do anyone knows a way how can I write for example 1 to stdout so when I pipe the script exactly 1 is on stdin of other script? I accept any kind of hack but I dont want to do redirection on invocation like ()sth>&1 | script.
I was going crazy trying to capture PowerShell output from a PowerShell command I executed from within a Python script. And it did not work because PowerShell does not properly write to STDOUT.
But I found some ways...
First is using the PowerShell command Write-Information:
Write-Information -Message "This goes to Stdout" -InformationAction Continue
The other is starting PowerShell with cmd and capture the output of cmd:
cmd.exe /C "powershell.exe -command "Write-Host 'This goes to Stdout'"

Execute a Program with arguments

I want to build a PowerShell script for invoking Python3. Now in shell this would be pretty simple but I cannot seem to get the following converted to PS:
../py/python3 myscript.py $#
I am lost somewhere in the maze of Start-Process, get-item, path building, ...
Is there any EASY way of doing that in PowerShell?
PowerShell is a shell, so for the most part, running programs is what it does well. I'm guessing you're converting a Unix shell script which is where $# comes from. The equivalent in PowerShell for that would probably be $args or #args:
../py/python3 myscript.py $args
Within a script, $args contains the arguments to that script. However, within a script block or function it will contain the arguments to that script block or function, so careful when abstracting things in your script.
invoke-expression -command "../py/python3 myscript.py" $#

Nested powershell parameters

In a powershell script I need to start the process powershell and tell it to run the script foo.ps1 like so:
start-process powershell C:\foodir\foo.ps1
But I ran into problems when I needed the script foo to be run with parameters. I tried some code like this:
start-process powershell (C:\foodir\foo.ps1 -paramforfoo test)
but this simply freezes the script when it gets to this line and throws no errors. I think it is trying to pass the parameter test to the powershell process and not to the script foo. How can I run this script with parameters?
Try using quotes to collect your command. E.g.
Start-Process powershell ".\Untitled3.ps1 -testparam 'hello world'"

Script echo current command in PowerShell

Suppose I'm running a PowerShell script that takes several input parameters. The command looks like:
psScript.ps1 -arg1 "arg1value" -arg2 "arg2value"
Is there a way to store this exact command in a variable within the script so that I can log it?
Specifically, I'd like to know what to assign to the variable $currentCommand:
$currentCommand = <something>
Write-Host "currently running script " $currentCommand
Such that the Write-Host output would be the exact command line used to invoke the script. If the script command was the same as above, for example, then the output would be:
currently running script psScript.ps1 -arg1 "arg1value" -arg2
"arg2value"
This may suit your needs:
Write-Host "currently running script " $myinvocation.Line
Reference
The $MyInvocation variable will have the information. Here is a good blog post about it.

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