TFSBuild Powershell step turning script arguments into strings. How to avoid this? - powershell

I've configured the following arguments in a Powershell build step: -protocol:http -portsToOpen 9512,9513,9512.
Once TFSBuild runs the whole script, it throws the following error:
"System.Int32[]". Error: "Cannot convert
"9512,9513,9515" to "System.Int32"
The problem is TFSBuild is running the script sorrounding 9512,9513,9515 with quots (i.e. '9512,9513,9515').
Is there any solution for this? One possible workaround would be running powershell.exe from a Command build step... But I'd like to know if there's some direct solution to this issue.

I don't use TFS but I can tell you PowerShell is parsing that as an integer array (System.Int32[]) and trying to pass that as an argument to -portsToOpen
If you don't have variables on that line you could use the stop parsing operator --% as that
directs Windows PowerShell to refrain from interpreting input as Windows PowerShell commands or expressions.
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
You could also actually put it in quotes so that PowerShell just treats it as a string. I could not find the documentation to back up how it expects input for that parameter so I am not sure.

Related

Can i run a exe with cmd or powershell if i have spaces in username?

Ex:
cmd /C start C:\Users\Bob Builder\Desktop\New Folder\test.exe
I'm trying to use cmd to start a file but since there are spaces in the path, cmd is throwing an error after Bob.
Error:
"Windows cannot find C:\Users\Bob. Make sure you typed the name
correctly, then try again."
The system cannot find the file C:\Users\Bob.
Its simply failing to accept the spaces. It's driving me crazy because I'm spoiled with C# working out of the box. I don't know much about this, I have been spending way too much time trying to figure this out. Some help would be greatly appreciated.
In order for a path that contains spaces to be recognized as a single path (argument), it must be quoted.
In order for an executable to execute in the current console window, synchronously, with its streams connected to the calling shell, it must be invoked directly, not via start.
Direct invocation from cmd.exe (only "..." quoting supported):
"C:\Users\Bob Builder\Desktop\New Folder\test.exe"
From PowerShell:
& 'C:\Users\Bob Builder\Desktop\New Folder\test.exe'
Note:
PowerShell also supports '...' strings (single-quoted), which are verbatim strings that are preferable to "..." (double-quoted) ones if you do not require expansion of variables (string interpolation) - see the conceptual about_Quoting_Rules help topic.
For syntactic reasons, PowerShell requires the use of &, the call operator to invoke commands that are quoted and/or contain variable references - see this answer for details.
By contrast, use start in cmd.exe / Start-Process in PowerShell (whose built-in alias is also start) to launch an executable in a new window (on Windows), asynchronously, with no (direct) ability to capture the launched executable's output:
From cmd.exe:
start "title" "C:\Users\Bob Builder\Desktop\New Folder\test.exe"
Note:
Specifying "title" - i.e. a self-chosen (console) window title - is required for syntactic reasons in this case: without it, the double-quoted path itself would be interpreted as the window title, and the - implied - executable to launch would be another cmd.exe instance.
Note that if you launch a GUI application this way, the title argument is irrelevant, because no new console window is created.
Conversely, if you launch a console application specified by double-quoted path and therefore must use a title argument, note that "" will result in the new window having no title.
From PowerShell (parameter -FilePath is positionally implied):
Start-Process 'C:\Users\Bob Builder\Desktop\New Folder\test.exe'
Note:
Start-Process does not support specifying a window title, so you may want to call cmd.exe's internal start command for that (or other features not supported by Start-Process, such as specifying the process priority).
To work around quoting problems, invoke cmd.exe's start from PowerShell by passing the entire start command as a single string to cmd /c:
cmd /c 'start "title" "C:\Users\Bob Builder\Desktop\New Folder\test.exe"'
cmd /C start "C:\Users\Bob Builder\Desktop\New Folder\test.exe"
Quotes are your friend. Sometimes even double quotes are too!
Seems like cmd won't work for me. Powershell worked with this script:
$env:Path += ";C:\Users\Bob Builder\Desktop\New Folder\"
test.exe

How can I solve this I suppose a MS PowerShell parsing error?

When I used the command below [1] to set my configuration variable MONGODB_URI, it gives an error [2].
I am using Windows PowerShell.
[1] >> heroku config:set MONGODB_URI='mongodb+srv://myprojectname:<mypassword>#cluster0.rkitj.mongodb.net/<myusername>?retryWrites=true&w=majority'
[2] The system cannot find the file specified.
'w' is not recognized as an internal or external command,
operable program or batch file.
Note: myprojectname, mypassword and myusername are placeholders for the actual value.
It looks like the heroku CLI entry point is a batch file, as implied by the wording of the error messages, which are cmd.exe's, not PowerShell's.
PowerShell doesn't take the special parsing needs of batch files (cmd.exe) into account when it synthesizes the actual command line to use behind the scenes, which involves re-quoting, using double quotes only, and only when PowerShell thinks quoting is needed.
In this case PowerShell does not double-quote (because the value contains no spaces), which breaks the batch-file invocation.
You have the following options:
You can use embedded quoting so as to ensure that the value part of your MONGODB_URI=... key-value pair is passed in double quotes; note the '"..."' quoting:
heroku config:set MONGODB_URI='"mongodb+srv://myprojectname:<mypassword>#cluster0.rkitj.mongodb.net/<myusername>?retryWrites=true&w=majority"'
Caveat: This shouldn't work, and currently only works because PowerShell's passing of arguments to external program is fundamentally broken as of PowerShell 7.1 - see this answer. Should this ever get fixed, the above will break.
If your command line doesn't involve any PowerShell variables and expressions, you can use --%, the stop-parsing symbol, which, however, in general, has many limitations (see this answer); essentially, everything after --% is copied verbatim to the target command line, except for expanding cmd.exe-style environment-variable references (e.g., %USERNAME%):
heroku config:set --% MONGODB_URI="mongodb+srv://myprojectname:<mypassword>#cluster0.rkitj.mongodb.net/<myusername>?retryWrites=true&w=majority"
If you're willing to install a module, you can use the ie function from the PSv3+ Native module (install with Install-Module Native from the PowerShell Gallery in PSv5+), which internally compensates for all of PowerShell's argument-passing and cmd.exe's argument-parsing quirks (it is implemented in a forward-compatible manner so that should PowerShell itself ever get fixed, the function will simply defer to PowerShell); that way, you can simply focus on meeting PowerShell's syntax requirements, and let ie handle the rest:
# 'ie' prepended to an invocation that uses only PowerShell syntax
ie heroku config:set MONGODB_URI='mongodb+srv://myprojectname:<mypassword>#cluster0.rkitj.mongodb.net/<myusername>?retryWrites=true&w=majority'

Invoking a command with variable evaluation in Octopus Deploy Powershell script

I have a simple Powershell script that I execute during an Octopus Deploy installation. This line works fine:
& $exe install --autostart
I runs an application identified by $exe variable with command line arguments "install --autostart".
Now I need to expand command line arguments with a value evaluated from a variable:
& $exe install --autostart -servicename=$serviceName
"$serviceName" is the variable that gets its value during the script execution. Whatever I do it's passed to the line above by variable name, not the value, e.g. it's passed as "$serviceName". I tried single and double quotes, nothing helps. As long it's a command invocation (triggered by the "&" symbol in the beginnging of the line), the rest of the line is interpreted verbatim, no variable substitions.
I used last couple of hours trying to figure this out and this is driving me mad. Any tips are appreciated.
I just did some testing on my side and it looks like if you'd like the variable passed in to the command to be evaluated as a variable it needs whitespace on both sides. So you would want to define your variable as $serviceName = "-servicename=*name*" or if that is not possible then create a new variable just before running the command
$tmpServicename = "-servicename=$($serviceName)"
& $exe install --autostart $tmpServiceName

How do I call exec in psake to an executable with a variable path?

I can't seem to call this executable correctly in my psake deploy script.
If I do this:
exec { "$ArchiverOutputDir\NServiceBus.Host.exe /install" }
It simply outputs this (and is clearly not calling the executable - just outputting the value of that expression):
c:\ReloDotNet2_ServiceEndpoints\Archiver\NServiceBus.Host.exe /install
But if I do this:
exec { c:\ReloDotNet2_ServiceEndpoints\Archiver\NServiceBus.Host.exe /install }
I get the expected output from the executable.
How do I correctly call an executable with a variable in the path to the executable in psake? If this is actually a PowerShell issue, please feel free to correct the question to reflect that insight.
I
Classic PowerShell issue. Try this instead:
exec { & "$ArchiverOutputDir\NServiceBus.Host.exe" /install }
PowerShell not only executes commands, it also evaluates expressions e.g.:
C:\PS> 2 + 2
4
C:\PS> "hello world"
hello world
What you have given to PowerShell at the beginning of a pipeline is a string expression which it faithfully evaluates and prints to the console. By using the call operator &, you're telling PowerShell that the following thing is either the name of a command (in a string) to be executed or a scriptblock to be executed. Technically you could also use . "some-command-name-or-path". The only difference is that for PowerShell commands, & creates a new scope to execute the command in and . doesn't. For external exes it makes no difference as far as I can tell which one you use but & is typically used.

Running msdeploy.exe from within Powershell

I'm trying to run the following command from within Powershell:
msdeploy -verb:sync -source:archiveDir=c:\KitchenPC\Build -dest:appHostConfig="KitchenPC",computerName=https://192.168.0.3:8172/msdeploy.axd,authType=Basic,userName=someuser,password="secret" -allowUntrusted
The docs say to simply substitute the : after each parameter with an =. So I've tried this:
msdeploy -verb=sync -source=archiveDir=c:\KitchenPC\Build -dest=appHostConfig="KitchenPC",computerName=https://192.168.0.3:8172/msdeploy.axd,authType=Basic,userName=someuser,password="secret" -allowUntrusted
However, I get the error:
Error: Unrecognized argument
'computerName=https://192.168.0.3:8172/msdeploy.axd'. All arguments
must begin with "-". Error count: 1.
I've checked the docs on provider settings, however they have no mention of their equivelent Powershell syntax.
How do you call msdeploy from powershell when the parameters have spaces?
Think this is already answered, just modify it.
Ex. include "KitchenPC" and "secret" using variables, and put the -dest part inside quotation marks.
Working Example:
msdeploy '-verb=sync' '-source=archiveDir=c:\KitchenPC\Build -dest=appHostConfig="KitchenPC",computerName=https://192.168.0.3:8172/msdeploy.axd,authType=Basic,userName=someuser,password="secret"' -allowUntrusted
(Note single quotes around each command line argument)