How to fix Folder Path error in PowerShell - powershell

I have this folder in my OneDrive and Just wondering how should I pass the path. Right now I'm getting "Folder not Found" when I try to do it like this.
$ServerRelativeUrl= "Documents/PC-OFFBOARD_USMPGWNCAT15C61-GZJY8T-01-Dec-0257/C$/'$Windows.~WS'"

With double-quoted " strings, you must escape characters with special meanings if you want them to be processed literally. PowerShell's escape character is the backtick `. The dollar-symbol $ must be prefixed with a backtick like this to be part of a literal file path:
"Documents/PC-OFFBOARD_USMPGWNCAT15C61-GZJY8T-01-Dec-0257/C`$/'`$Windows.~WS'"
Alternatively, you can use a single-quoted ' string instead, making sure to escape the literal single-quotes with two single-quotes '' (backticks won't escape in a literal string):
'Documents/PC-OFFBOARD_USMPGWNCAT15C61-GZJY8T-01-Dec-0257/C$/''$Windows.~WS'''
This loses your ability to insert actual intended variables though. You can however rely on the format operator in this case. To insert the literal string '$Windows.~WS' into the path, for example:
$folderName = '''$Windows.~WS'''
$fullPath = 'Documents/PC-OFFBOARD_USMPGWNCAT15C61-GZJY8T-01-Dec-0257/C$/{0}' -f $folderName

Related

Powershell: Writing string with escaped characters to file

I have a project where I'm trying to dynamically prepare a Powershell script, then write it out to a file for later execution.
Here's a minimal example of the issue:
# The string that I want to write out, having most special characters
$_output_str = "~##$%&*()-_=+{}[]<>?/.,'`"``;!"
# Write it out directly
Write-Output "$_output_str"
This is putting a string with escaped special characters into a variable, then writing the value of that variable out to stdout. It works as expected:
~##$%&*()-_=+{}[]<>?/.,'"`;!
Now, let's try storing that command in a file for later execution.
# The string that I want to write out, having most special characters
$_output_str = "~##$%&*()-_=+{}[]<>?/.,'`"``;!"
# Turn it into a string command
$_cmd = "Write-Output `"$_output_str`""
# Write the command out to a file
"$_cmd" | Out-File "execution.ps1"
And now let's try executing that file:
powershell.exe .\execution.ps1
This throws an error:
At C:\{MYPATH}\execution.ps1:1 char:43
+ Write-Output "~##$%&*()-_=+{}[]<>?/.,'"`;!"
+ ~
The string is missing the terminator: ".
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString
OK, so let's look at the content that was written to the file. This is what execution.ps1 contains:
Write-Output "~##$%&*()-_=+{}[]<>?/.,'"`;!"
Notice that the " and the backtick near the end of the string are no longer escaped. So for some reason, when creating the $_cmd string, it got rid of my escape sequences.
How can I prevent this from happening?
Use single-quoted here-string for the value so it doesn't get expanded.
$_output_str = #'
~##$%&*()-_=+{}[]<>?/.,'"`;!
'#
You can also use regular single-quoted strings but keep in mind that you'll have to double any single-quote part of the string.
# The single quote is escaped by doubling it, meaning the final
# representation will be slightly different
$_output_str = '~##$%&*()-_=+{}[]<>?/.,''"`;!'
# Actual value (the two '' were escaped into a single ')
# '~##$%&*()-_=+{}[]<>?/.,'"`;!'
It is still better than double-quoted strings in any cases.
When you use a double-quoted strings, everything that can get evaluated get evaluated. Your backticks serves to escape the character right after but they are not part of the final representation of the string.
Double-quoted strings
A string enclosed in double quotation marks is an expandable string.
Variable names preceded by a dollar sign ($) are replaced with the
variable's value before the string is passed to the command for
processing.
...
expressions are evaluated, and the result is inserted in the string.
I recommend you take a look at the official documentation for more information. About_Quoting_Rules

How to get around using apostrophe in double quotes with Powershell

I am working with Powershell. My issue is that my file path (which does not exist on a local computer) has an apostrophe in it. Powershell is seeing this as a single quote, so it is giving me the following error: The string is missing the terminator: '. I thought that I could escape the single quote using a backtick, but that gave me the same error.
The error does not occur when I am doing the first line of code, and I don't even need the backtick for that part. I can even see that the contents of the variable matches up with the file path that I am using. It is only when I am doing the invoke-expression part that it is giving me the error.
I am using https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-expression?view=powershell-7, so I don't think the second line of the code is the problem.
My code is listed below:
$code = "\\example\example\John_Doe`'s_Folder\example.ps1"
invoke-expression -command $code
I have also tried wrapping the entire file path in double-quotes and single-quotes, but my program did not like that either. I can't remove the apostrophe as we have over a hundred of systems that are directing to John_Doe's_Folder.
Invoke-Expression should generally be avoided; definitely don't use it to invoke a script or external program.
In your case, simply use &, the call operator to invoke your script via the path stored in variable $code (see this answer for background information), in which case the embedded ' needs no escaping at all:
$code = "\\example\example\John_Doe's_Folder\example.ps1"
& $code
As for what you tried:
"\\example\example\John_Doe`'s_Folder\example.ps1" turns into the following verbatim string content:
\\example\example\John_Doe's_Folder\example.ps1
That is, the ` was removed by PowerShell's parsing of the "..." string literal itself, inside of which ` acts as the escape character; since escape sequence `' has no special meaning, the ` is simply removed.
For the ` to "survive", you need to escape the ` char. itself, which you can do with ``:
"\\example\example\John_Doe``'s_Folder\example.ps1"

Searching for backslash in a string with Powershell

I need to search for the amount of backslashes in a string to determine some file path parameters. I have not worked out a way to seach for a backslash without Powershell thinking it is an escapee character.
([regex]::Matches($FilePath, "\" )).count
Or
$a -match "\"
These both come up with an error "Illegal \ at end of pattern"
Thanks!
You can escape a backslash with a backslash:
[Regex]::Matches($FilePath, "\\").Count

Perl q function or single quote doesn't return the string literal of UNC path correctly

Perl's q function or single quote is supposed to return the string literal as typed (except \'). But it doesn't work as expected for the following scenario.
I want to print the following UNC path
\\dir1\dir2\dir3
So I have used
my $path = q(\\dir1\dir2\dir3);
OR
my $path = '\\dir1\dir2\dir3';
But this skips one backslash at the front.
So if I print it i.e. print $path; it prints
\dir1\dir2\dir3
I want to know why? I have to type 3 or 4 backslashes at the beginning of the UNC path to make it work as expected. What am I missing?
From perldoc perlop:
q/STRING/
'STRING'
A single-quoted, literal string. A backslash represents a backslash unless followed by the delimiter or another backslash, in which case the delimiter or backslash is interpolated.
Change:
my $path = q(\\dir1\dir2\dir3);
to:
my $path = q(\\\dir1\dir2\dir3);
As for why, it's because Perl lets you include the quote delimiter in your string by escaping it with a backslash:
my $single_quote = 'This is a single quote: \'';
But if a backslash before the delimiter always escaped the delimiter, there would be no way to end a string with a backslash:
my $backslash = 'This is a backslash: \'; # nope
Allowing backslashes to be escaped too takes care of that:
my $backslash = 'This is a backslash: \\';
Interestingly enough, there is only one way to type in double backslashes in a perl string without it being interpolated as a single backslash.
As all the other answers showed, any of the quote operators treat backslashes as a backslash unless there is another one following it directly.
The only way to get the double backslashes to display exactly as you have typed them is to use a single quote here-doc.
my $path = <<'VISTA';
\\dir1\dir2\dir3
VISTA
chomp $path;
print $path."\n";
Would print it exactly as you've typed it in.

escaping single quote sign in PowerShell

I have a replace statement in my code whereby Band's is being replaced by Cig's. However when I put single quote it took the first sentence... Example 'Band'
I tried to use double quote but it does not work. Do you know how to escape the single quote sign?
-replace 'Band's', 'Cig's'
See Escape characters, Delimiters and Quotes and Get-Help about_Quoting_Rules from the built-in help (as pointed out by as Nacimota).
To include a ' inside a single-quoted string, simply double it up as ''. (Single-quote literals don't support any of the other escape characters.)
> "Band's Toothpaste" -replace 'Band''s', 'Cig''s'
Or, simply switch to double-quotes. (Double-quote literals are required when wishing to use interpolation or escape characters.)
> "Band's Toothpaste" -replace "Band's", "Cig's"
(Don't forget that -replace uses a regular expression)
Escape a single quote with two single quotes:
"Band's Toothpaste" -replace 'Band''s', 'Cig''s'
Also, this is a duplicate of
Can I use a single quote in a Powershell 'string'?
For trivial cases, you can use embedded escape characters. For more complex cases, you can use here-strings.
$Find = [regex]::escape(#'
Band's
'#)
$Replace = #'
Cig's
'#
"Band's Toothpaste" -replace $Find,$Replace
Then put the literal text you want to search for and replace in the here-strings.
Normal quoting rules don't apply within the here-string #' - '# delimiters, so you can put whatever kind of quotes you want, wherever you want them without needing any escape characters.
The [regex]::excape() on $Find will take care of doing the backslash escapes on any regex reserved characters that might be in the search pattern.