Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing parameters to powershell script

I'm trying to run a powershell script from the run dialog (will be used as a scheduled task), and I'm having troubles passing parameters.

The script will take in two parameters, named title and msg. The script is located in: D:\Tasks Scripts\Powershell\script.ps1

This is what I'm trying to do:

powershell.exe -noexit 'D:\Tasks Scripts\Powershell\script.ps1' -title 'Hello world' -msg 'This is a test message'

But it fails upon reading the parameters.

Running .\script.ps1 -title 'Hello world' -msg 'This is a test message' on powershell works fine.

like image 924
desto Avatar asked Sep 27 '13 16:09

desto


2 Answers

Use -file before the path to your script:

powershell.exe -noexit -file 'D:\Tasks Scripts\Powershell\script.ps1' etc...
like image 59
Nate Hekman Avatar answered Oct 17 '22 10:10

Nate Hekman


I usually run powershell scripts from cmd.exe because this is portable (works out-of-the-box on others' computers, like developer folks or clients): no need to worry about Set-ExecutionPolicy or associating the .ps1 extension.

I create the file with .cmd extension (instead of .ps1), and copy&paste a short, constant code to the first line(s) that invokes powershell.exe and passes the rest of the file to it.
Passing arguments is tricky. I have multiple variants of the constant code because the general case is painful.

  1. when not passing arguments, the .cmd file looks like this:

    @powershell -c ".(iex('{#'+(gc '%~f0' -raw)+'}'))" & goto :eof
    # ...arbitrary PS code here...
    write-host hello, world!
    

    This uses the -Command argument of powershell.exe. Powershell reads the .cmd file as text, puts it in a ScriptBlock with the first line commented out, and evaluates it with the '.' command. Further command line arguments can be added to the Powershell invocation as required (e.g. -ExecutionPolicy Unrestricted, -Sta etc.)

  2. when passing arguments that do not contain spaces or are 'single-quoted' (which is non-standard in cmd.exe), the one-liner is this:

    @powershell -c ".(iex('{#'+(gc($argv0='%~f0') -raw)+'}'))" %* & goto :eof
    
    write-host this is $argv0 arguments: "[$($args -join '] [')]"
    

    param() declarations could be used as well, $args is not obligatory.
    $argv0 is used to compensate for the missing $MyInvocation.PS* info.
    Examples:

    G:\>lala.cmd
    this is G:\lala.cmd arguments: []
    
    G:\>lala.cmd "1 2" "3 4"
    this is G:\lala.cmd arguments: [1] [2] [3] [4]
    
    G:\>lala.cmd '1 2' '3 4'
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
  3. when passing arguments that are "double-quoted" but do not contain the & and ' characters, I use a two-liner to replace all " with '

    @echo off& set A= %*& set B=@powershell -c "$argv0='%~f0';.(iex('{'
    %B%+(gc $argv0|select -skip 2|out-string)+'}'))" %A:"='%&goto :eof
    
    write-host this is $argv0 arguments: "[$($args -join '] [')]"
    

    (Note that the space is important in the A= %* assignment for the argument-less case.)
    Results:

    G:\>lala.cmd
    this is G:\lala.cmd arguments: []
    
    G:\>lala.cmd "1 2" "3 4"
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
    G:\>lala.cmd '1 2' '3 4'
    this is G:\lala.cmd arguments: [1 2] [3 4]
    
  4. the most general case passes the arguments via environment variables thus Powershell's param() declaration does not work. In this case the arguments are expected to be "double-quoted" and may contain ' or & (except for the path of the .cmd file itself):

    ;@echo off & setlocal & set A=1& set ARGV0=%~f0
    ;:loop
    ;set /A A+=1& set ARG%A%=%1& shift& if defined ARG%A% goto :loop
    ;powershell -c ".(iex('{',(gc '%ARGV0%'|?{$_ -notlike ';*'}),'}'|out-string))"
    ;endlocal & goto :eof
    for ($i,$arg=1,@(); test-path -li "env:ARG$i"; $i+=1) { $arg += iex("(`${env:ARG$i}).Trim('`"')") }
    write-host this is $env:argv0 arguments: "[$($arg -join '] [')]"
    write-host arg[5] is ($arg[5]|%{if($_){$_}else{'$null'}})
    

    (Note that in the first line A=1& must not contain space.)
    Result:

    G:\>lala.cmd "a b" "c d" "e&f" 'g' "h^j"
    this is G:\lala.cmd arguments: [a b] [c d] [e&f] ['g'] [h^j]
    arg[5] is $null
    
like image 39
robert4 Avatar answered Oct 17 '22 10:10

robert4