6

I'm trying to the following powershell script in cmd. Here's a trivial example:

$path = "c:\"
cd $path
ls

Some PowerShell script of multiple lines and with quotation marks.

I read this post and @Alex's answer in this post, but putting multiple lines together with ; between them didn't work:

C:\Users\abcd>powershell "&c:\ ; ls"
& : The term 'c:\' 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:2
+ &c:\ ; ls
+  ~~~
    + CategoryInfo          : ObjectNotFound: (c:\:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS: My actual task is to run the following (I provided the trivial task above, since not everyone has the database).

$tabular_server = "abc_123\Tabular"

[Reflection.Assembly]::LoadWithPartialName("Microsoft.AnalysisServices")
$server = New-Object Microsoft.AnalysisServices.Server
$server.connect($tabular_server)
$db = $server.Databases.Item("db_name")

$db.Process("ProcessClear")
$db.Process("ProcessDefault")
$server.Disconnect()
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
YJZ
  • 3,934
  • 11
  • 43
  • 67
  • I would recommend dispensing with `cmd.exe` and just use PowerShell directly. – Bill_Stewart Jan 16 '18 at 22:35
  • thank you @Bill_Stewart the reason to use cmd to call powershell is, ultimately i'm putting everything in `R`. It seems `R` only has `system` command that executes cmd, and no command that can execute powershell script. – YJZ Jan 16 '18 at 22:55

3 Answers3

23

& is PowerShell's call operator. The operator is used for invoking commands/functions that come as strings (e.g. because someone wanted to represent them a variable, or their path contains spaces) as well as scriptblocks.

In your case it would suffice to just put your statements in a row, separated by semicolons:

powershell.exe -Command "$path = 'c:\'; cd $path; ls"

However, personally I prefer putting the statements in a scriptblock (which is where the call operator comes into play):

powershell.exe -Command "&{$path = 'c:\'; cd $path; ls}"

Either way should work, though. Beware that inside double-quoted command strings you need to either use single quotes or escape nested double quotes.

With all of that said, for longer, more complex PowerShell code inline execution via the -Command parameter is not recommended. Better write the code to a PowerShell script and run it like this:

powershell.exe -File "C:\path\to\your.ps1"
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • thank you @Ansgar Wiechers the reason i want to put it inline is so that I just need to send people the script, not script + a `.ps1` file. - any further advice how people usually handle this? thank u- – YJZ Jan 16 '18 at 22:54
  • 1
    I would just send them the PowerShell script with the instruction to run it from a PowerShell console where the `powershell.exe -File` isn't needed. – Ansgar Wiechers Jan 16 '18 at 22:57
0

in c:\test.bat

    SET strArgList= C:\powershell\sample.ps1 
    SET strArgList=%strArgList% -Workbook C:\excel_template\TEMPLATE.xlsm 
    SET strArgList=%strArgList% -TextDir C:\text\Output  
    SET strArgList=%strArgList% -ExcelDir C:\Excel 
    SET strArgList=%strArgList% -FileMask *.txt

    echo %strArgList%
    PowerShell.exe C:\powershell\sample.ps1 -Workbook C:\excel_template\TEMPLATE.xlsm -TextDir C:\text\Output -ExcelDir C:\Excel -FileMask *.txt

    PowerShell.exe %strArgList%
0

Works for me.

powershell $path = 'c:\'; cd $path; ls

powershell c:\; ls

Here's a way to quote the pipe:

powershell ls c:\ ^| measure

This might work, but I don't have the assembly.

powershell {$tabular_server = 'abc_123\Tabular'; [Reflection.Assembly]::LoadWithPartialName('Microsoft.AnalysisServices'); $server = New-Object Microsoft.AnalysisServices.Server; $server.connect($tabular_server); $db = $server.Databases.Item('db_name'); $db.Process('ProcessClear'); $db.Process('ProcessDefault'); $server.Disconnect()}

EDIT:

In cmd, you can continue a line with "^". It works in a limited way running powershell at the cmd prompt, without open doublequotes:

powershell echo (1 + ^
More? 2 + ^
More? 3)
6

Thus. I had to use singlequotes. Cmd would eat the doublequotes. No scriptblock. Again, I don't have the assembly.

powershell $tabular_server = 'abc_123\Tabular'; ^
[Reflection.Assembly]::LoadWithPartialName('Microsoft.AnalysisServices'); ^
$server = New-Object Microsoft.AnalysisServices.Server; ^
$server.connect($tabular_server); $db = ^
$server.Databases.Item('db_name'); $db.Process('ProcessClear'); ^
$db.Process('ProcessDefault'); $server.Disconnect()

This definitely works for me:

powershell using assembly System.Windows.Forms; ^
using namespace System.Windows.Forms; ^
[messagebox]::show('hello world')
js2010
  • 23,033
  • 6
  • 64
  • 66