简体   繁体   中英

How to run a CMD task inside of PowerShell?

I am trying to run a CMD task inside of a PowerShell script that will open up a new tab in Google Chrome. I am running this command inside an Azure DevOps pipeline.

The task I am attempting to run is:

start chrome --user-data-dir="ChromeProfiles\Profile$profile" --disable-default-apps --new-window "$($reportHtmlFile)"

When I run this command from my local command prompt, a new tab opens and works as expected. To run it from my PowerShell window I run:

cmd /c echo start chrome --user-data-dir="ChromeProfiles\Profile$profile" --disable-default-apps --new-window "$($reportHtmlFile)" | cmd.exe

Both the above commands work as expected however, trying to run them from Azure DevOps I am getting an error saying:

+ ... " --disable-default-apps --new-window "$($reportHtmlFile)"" | cmd.exe
+                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The string is missing the terminator: ".
At D:\Agent\instance01\Workspace\20\s\pbi-load-test-tool\Run_Load_Test_Only.ps1:59 char:1
+ 
Missing closing ')' in expression.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

I have tried the following:

"start chrome --user-data-dir="ChromeProfiles\Profile$profile" --disable-default-apps --new-window "$($reportHtmlFile)"" | cmd.exe

& "start chrome --user-data-dir="ChromeProfiles\Profile$profile" --disable-default-apps --new-window "$($reportHtmlFile)" | cmd.exe"

Is there a syntactical error or is this a shortcoming with Azure DevOps?

What's Going on:

Your arguments are getting mangled because they contain quotes.

When you run this the way you're running it now, PowerShell will try to handle the quotes in the arguments before passing it to the exe.

The solution: Use Splatting

Splatting is a part of the PowerShell language that lets you pass structured arguments to a command. You can Splat a [Hashtable] to provide named arguments (if you're calling a function or cmdlet). You can also Splat an [Object[]] to provide arguments positionally.

  1. Create an array out of all of your arguments:

In your case, that would be:

$startArgs = @(
    # The user-data-dir probably wants double quotes
    # so we use backticks to embed them.
    "--user-data-dir=`"ChromeProfiles\Profile$profile`""
    '--disable-default-apps'
    '--new-window'
    "$($reportHtmlFile)"
)
  1. Call with splatting:
start @startArgs

Doing things this way will ensure that each argument is sent exactly the way you want it, with complete control over how arguments will be quoted.

Also: avoid $profile

$profile is the name of an automatic variable in PowerShell pointing to the PowerShell profile. I suspect you're interested in a chrome profile, not a PowerShell profile, so I would pick a different variable name that would better describe your purpose, rather than risk having an automatic variable provide a bad result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM