Using variable which contains $ as password - powershell

I'm trying to deploy something through Octopus V4 and in my project variables, I got a password in which I have the special character $.
Assigning this Octo variable to a PowerShell variable will transform the string because PowerShell surely thinks that there is a variable in it. For instance, if I've got this:
azerty$qwerty
I'll end up with this:
azertyerty
So when it comes to start the deployed service with the appropriate credentials, it won't work. Just for the record: before starting the service, I'm creating it with the New-Service command in the deployment script of the project.
I read here and there that I need to use single quotes instead of double quotes to make it work but here my hands are tied since I'm just getting the variable from Octopus doing that:
$mypassword = $OctopusParameters["password"]
Any clue about how to keep the full string, $ included?

Please see About Quoting Rules as this may help.
When you enclose a string in single-quotation marks (a single-quoted string), the string is passed to the command exactly as you type it. No substitution is performed. When you enclose a string in double quotation marks (a double-quoted string), variable names that are preceded by a dollar sign ($) are replaced with the variable's value before the string is passed to the command for processing.
See below for an example of this behavior:
PS> $for = "my string"
PS> "test$for"
testmy string
PS> 'test$for'
test$for
Octopus may have its own way of dealing with this. I would try using double single quotes around the string and see if that helps, like ''my$string''.
I did also read in a forum that someone had success using the following cmdlet for password:
Set-OctopusVariable -Name 'password' -Value 'password123$'

This might be a silly question, but have you tried this already and it didn't work?
If you are using Octopus with the syntax:
$mypassword = $OctopusParameters["password"]
Octopus will not do any replacement of the value set in the Octopus parameter. Your foreseen issue will only appear if you are setting the password in double quotes inside Powershell directly, as in:
$mypassword = "azerty$qwerty"
And if you are doing this in Powershell, the correct way to set it will be to escape the $ with the tick (`) as in:
$mypassword = "azerty`$qwerty"

Related

sqlplus - No characters are allowed after a here-string header but before the end of the line

I'm trying to use sqlplus to do an Oracle query for the first time in a PowerShell script. I get this error message:
At line:1 char:73
+ ... user/pw#RRRPRD.company.net:1521/RRRPRDC #"C:\Users\ ...
+ ~
No characters are allowed after a here-string header but before the end of the line.
It seems to be pointing to the C: after #". Any ideas? I seem to be doing what is at this example. I get the same error when I try to do echoargs of the connection info.
This is my powershell code I am testing at the command line since it hangs forever running the program:
sqlplus user/pw#RRRPRD.company.net:1521/RRRPRDC #"C:\Users\me\Documents\2021\temp endToEnd\short.sql"
This is using powershell 5.1. Any ideas? I see here string header, but since I am following the example that was accepted in the link for sqlplus above, it's unclear to me what's wrong with it.
Replace
#"C:\Users\me\Documents\2021\temp endToEnd\short.sql"
with any of the following:
`#"C:\Users\me\Documents\2021\temp endToEnd\short.sql"
"#C:\Users\me\Documents\2021\temp endToEnd\short.sql"
'#C:\Users\me\Documents\2021\temp endToEnd\short.sql'
Note: Using a verbatim (single-quoted) string ('...') is arguably the best choice here, given that the path contains no variable references; if it did, a expandable (double-quoted) string ("...") would be equired.
All variations end up passing the following string verbatim to sqlplus, which I presume is your intent:
#C:\Users\me\Documents\2021\temp endToEnd\short.sql
Presumably, you're trying to pass # as a verbatim part of an argument to sqlplus - a common convention among CLIs is to use #<file-path> to request that argument data be taken from a file rather than using the argument value itself.
However, unlike in other shells, # is a metacharacter in PowerShell that serves a variety of purposes.
Thus, a # that should be a verbatim character at the start of an argument must either be escaped (with `) or part of a quoted string, as shown above. See the conceptual about_Special_Characters help topic.
If an unescaped argument-initial # is followed by " or ', PowerShell thinks you're trying to create a here-string, which has special, multi-line syntax requirements; the error message indicates that they're not met.

PowerShell - Merge two variables into one

I'm learning PowerShell so please forgive (what I'm sure is) a simple question.
I'm used to coding BATCH scripts and if I wanted to merge %USERDOMAIN% and %USERNAME% I would:
set zFullUsername=%USERDOMAIN%\%USERNAME%
echo %zFullUsername%
How can I do the same in PowerShell?
Thank you for your time.
On a supported Operating System, I wouldn't even bother with environment variables for this:
$zFullUsername = whoami
Then just access it as required:
$zFullUsername
In PowerShell, you can access environment variables in a few different ways. The way I recommend is to use the $env:VAR variable to access them.
$user = $env:USERNAME
$domain = $env:USERDOMAIN
echo "$domain\$user"
Note: \ is not an escape character in the PowerShell parser, ` is.
Similarly to rendering the echo command (echo is an alias of Write-Output btw) you can create a username variable like so:
$fullUserName = "$domain\$user"
Or you can skip right to creating $fullUserName straight from the environment variables:
$fullUserName = "${env:USERDOMAIN}\${env:USERNAME}"
Note: When variables have non-alphanumeric characters in them, the ${} sequence tells PowerShell everything between the ${} is part of the variable name to expand.
It seems the : in $env:VAR is actually an exception to this rule, as"Username: $env:USERNAME" does render correctly. So the ${} sequence above is optional.
To avoid confusion when trying to apply this answer in other areas, if you needed to insert the value of an object property or some other expression within a string itself, you would use a sub-expression within the string instead, which is the $() sequence:
$someVar = "Name: $($someObject.Name)"
When using either ${} or $(), whitespace is not allowed to pad the outer {} or ().

Putting Powershell variable in double quotes shows Object type instead of value

I see this problem in several area, but here is an example
I read an xml document like this and print out a value
[xml]$pom = get-content -path pom.xml
PS C:\> $pom.project.artifactId
nexus-peter-test-service
However, if I put the value in double quotes, I get this
"$pom.project.artifactId"
System.Xml.XmlDocument.project.artifactId
I need the value in double quotes because it's part of a long string. In my case, a url. So I'm using it like this:
"/$pom.project.artifactId/"
Why does Powershell change the meaning of the variable when in it's double quotes? And how can I fix this?
The problem is that the interpolation stops at the period. It interpolates "$pom" - which stringifies as the class name - followed by the literal string ".project.artifactId".
To interpolate anything more complex than a simple variable name, you need to wrap $(...) around the expression:
"$($pom.project.artifactId)"

Pipeline Array Variable (Classic) Causing powershell exception [duplicate]

I try to concatenate string to construct a path:
$SourceDirectoryPath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug"
$TargetFilePath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug/" + $(Release.ReleaseName) +$(Release.EnvironmentName)
but instead of getting string concatenated I get error for the second line:
d:\a\r1\a : The term 'd:\a\r1\a' 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
D:\a_temp\9de874c9-3acd-4a19-a4dd-763074d38e40.ps1:2 char:25
where obviously d:\a\r1\a is a $(System.DefaultWorkingDirectory) but why it throws this error instead of just concatenating the string?
tl;dr
It is Azure that expands $(System.DefaultWorkingDirectory) before PowerShell sees the resulting commands; if the expanded $(...) value is to be seen as a string by PowerShell, it must be enclosed in quotes ('$(...)'):
Using $(...) (Azure macro syntax) embeds the Azure variable's verbatim value in the command text that PowerShell ends up interpreting.
Note: Azure's macro syntax - which is evaluated before PowerShell sees the resulting command text - is not to be confused with PowerShell's own subexpression operator, $(...).
For string values this means that you situationally have to surround the macro with quotes in order to make it work syntactically in PowerShell code, for which '...'-quoting (single-quoting) is best: '$(System.DefaultWorkingDirectory)'
Shayki Abramczyk's answer provides an effective solution, but let me provide some background information:
The variable expansion (substitution) that Azure performs via macro syntax ($(...)) functions like a preprocessor: it replaces the referenced variable with its verbatim value.
You need to make sure that this verbatim value works syntactically in the context of the target command.
As currently written:
$SourceDirectoryPath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug"
turns into the following command seen by PowerShell, assuming that the value of Azure property System.DefaultWorkingDirectory is d:\a\r1\a:
$SourceDirectoryPath = d:\a\r1\a + "/solution/project/bin/Debug"
This is a broken PowerShell command, because d:\a\r1\a - due to lack of quoting - is interpreted as a command name or path; that is, an attempt is made to execute putative executable d:\a\r1\a - see about_Parsing.
Therefore, in order for PowerShell to recognize the Azure-expanded value d:\a\r1\a as a string, you need to quote it - see about_Quoting_Rules.
Since the expanded-by-Azure value needs no further interpolation, single quotes are the best choice (for both operands, actually):
$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)' + '/solution/project/bin/Debug'
In fact, you don't need string concatenation (+) at all in your case:
$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)/solution/project/bin/Debug'
You could even combine that with expandable PowerShell strings ("..."), as long as the Azure-expanded value doesn't contain $-prefixed tokens that PowerShell could end up interpreting (unless that is your (unusual) intent).
One caveat re something like "$(System.DefaultWorkingDirectory)/$projectRoot/bin/Debug" (mixing an Azure-expanded value with a PowerShell variable reference) is that Azure's macro syntax ($(...)) looks the same as PowerShell's own subexpression operator, which is typically - but not exclusively - used in order to embed expressions in expandable strings (e.g., in pure PowerShell code, "1 + 1 equals $(1 + 1)").
As of this writing, the Define variables Azure help topic doesn't spell it out, but based on the official comment in a GitHub docs issue, ambiguity is avoided as follows:
There is no escape mechanism; instead, $(...) constructs that do not refer to Azure variables are left unchanged and therefore passed through to PowerShell.
In the typical case, PowerShell expressions will not look like an Azure variable reference (e.g, $($foo.bar) rather than $(foo.bar)), though hypothetically there can be ambiguity: $(hostname), which is a valid PowerShell subexpression, could be preempted by Azure if a hostname Azure variable were defined.
In such a corner case, the solution is to avoid use of an inline script and instead place the code in an external script file.
You need to add quotes " " in the variables:
$SourceDirectoryPath = "$(System.DefaultWorkingDirectory)" + "/solution/project/bin/Debug"
$TargetFilePath = "$(System.DefaultWorkingDirectory)" + "/solution/project/bin/Debug/" + "$(Release.ReleaseName)" + "$(Release.EnvironmentName)"
This should work as well. $( ) outside of doublequotes would only be used to combine two or more statements. Most people don't even know about it.
This is actually incorrect. I didn't know Azure Pipeline syntax. It just shows how confusing combining both Powershell and Azure Pipeline can be. This would work if $System were a Powershell object, not an Azure macro.
$SourceDirectoryPath = $System.DefaultWorkingDirectory + '/solution/project/bin/Debug'

Ignore space in string stored in argument perl

I'm trying to execute a .VB script along with some other arguments.
I'm calling system("$cmd"), where
my $cmd = "Report.exe $app_env $rpt_Dir $eff_date";
and
my $rpt_Dir = "\\\\server\\folder\\Target Report\\test";
The problem I am having is that (I think) the space between "Target Report" is making the script treating it as 2 arguments.
And the reason why I didn't just surround the path with "" and pass it as an argument instead of saving it to a variable is that the path changes based on the date.
And it's not a first choice that I change the code in the .VB script.
On Windows, the system call uses cmd.exe to process commands, so you need double quotes around any parameters that contain spaces
Set your $cmd up like this
my $cmd = qq{Report.exe $app_env "$rpt_Dir" $eff_date};
The qq{...} construction is identical to ordinary double quotes, but it allows you to choose your own delimiters so that you don't have to escape any embedded double quotes
Then you can write
system($cmd);
It is wrong to put quotes around a solitary scalar variable
You can pass an array of args to system. If you do this, you won't be tripped over by quote interpolation.
system ( "Report.exe", $app_env, $rpt_Dir, $eff_date );
You can simply enclose the $rpt_Dir variable in single quotes:
my $cmd = "Report.exe $app_env '$rpt_Dir' $eff_date";
and it will be treated as a single arguement