You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Discussion: Use literal paths for OutFile parameter on Invoke-RestMethod / Invoke-WebRequest #3174
When using square brackets in the OutFile parameter of the web cmdlets the square brackets in the path act as a wildcard option/range operator.
Hence any square brackets in the OutFile parameter causes an error for the cmdlets.
Personally, when downloading a file, I always use a literal path, instead of specifying a file with wildcard support.
I would like to start a discussion if it makes sense to treat the OutFile parameter as a literal path.
Any opinions on that?
Maybe someone could contribute scenarios where wildcard support makes sense.
Note: Of course there are several workarounds in PowerShell to overcome this minor lack of comfort.
Creates a ReadMe[Powershell].md file in current directory.
Actual behavior
Invoke-WebRequest : Cannot perform operation because the wildcard path ReadMe[Powershell].md did not resolve to a file.
At line:1 char:1+Invoke-WebRequest https://raw.githubusercontent.com/PowerShell/PowerS ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (ReadMe[Powershell].md:String) [Invoke-WebRequest], FileNotFoundException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Environment data
>$PSVersionTable
Name Value
---------
PSVersion 5.1.14393.693
PSEdition Desktop
PSCompatibleVersions {1.0,2.0,3.0,4.0...}
BuildVersion 10.0.14393.693
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Reacted by Keith Hill, Arvind Chembarpu, s-furui, EugeneKosmin, Chris Magnuson, Rain Sallow (/u/ta11ow) and Michael Klement
Agree that -OutFile makes more sense as a literal path. (It only makes sense as a literal path?). If the wildcard resolves to multiple files then Invoke-WebRequest throws an exception.
But there could be scripts which depend on the wildcard resolving to a single filename - that does work, so it might be a breaking change. In that case -LiteralOutFile as a new parameter?
The third parameter sets whether ResolveFilePath treats it as literal or not, so changing that to true should make it resolve as a literal path and fix this.
I can't see any other calls to QualifyFilePath, suggests there wouldn't be much other impact, but I'm not certain.
I think in general, output paths should be literalpaths. The behavior of matching a file seems unpredictable at best and clobbering something unintentional at worst.
@PowerShell/powershell-committee reviewed this and believe the right approach is to rename -OutFile to -Path (aliased as -OutFile) and add a -LiteralPath parameter. Existing -OutFile can be used with current globbing behavior to match a single file using a wildcard. For example, if you have a file called helloworld.txt and you want to overwrite it with the output, you can use -OutFile hello*.
ThreeFive-O You mention there are work arounds for this, can you add them as a comment?
I am trying to OutFile to a file that has [1] in the name but I cannot figure out how to escape the [] characters. I tried ` and \ but they do not escape the [] characters.
This is because typically the bare strings in a parameter are treated as expandable strings, which means that the backtick is treated as a PS escape character first and evaluated before being passed to the internals. As a result, you need to escape the escape character so PS's expandable string evaluation doesn't eat it. The other option is to force PS to recognise it as a literal string.
While your escaping technique is correct and ensures that the file path is accepted, there is a bug that affects most cmdlets in that they then use the escaped path as a literal path on output-file creation, which means that the ` chars. are unexpectedly retained - see #9475.
Therefore, the cumbersome workaround for now is to:
escape the input path so that it is accepted
and afterwards rename the incorrectly named file by removing ` instances from it.
Activity
HumanEquivalentUnit commentedon Oct 6, 2017
Agree that
-OutFilemakes more sense as a literal path. (It only makes sense as a literal path?). If the wildcard resolves to multiple files thenInvoke-WebRequestthrows an exception.But there could be scripts which depend on the wildcard resolving to a single filename - that does work, so it might be a breaking change. In that case
-LiteralOutFileas a new parameter?Here is the code which saves to the file referencing a property
QualifiedOutFile, which is defined here, it callsreturn (QualifyFilePath(OutFile));That's defined here
The third parameter sets whether ResolveFilePath treats it as literal or not, so changing that to
trueshould make it resolve as a literal path and fix this.I can't see any other calls to
QualifyFilePath, suggests there wouldn't be much other impact, but I'm not certain.SteveL-MSFT commentedon Oct 6, 2017
I think in general, output paths should be literalpaths. The behavior of matching a file seems unpredictable at best and clobbering something unintentional at worst.
SteveL-MSFT commentedon Nov 30, 2017
@PowerShell/powershell-committee reviewed this and believe the right approach is to rename
-OutFileto-Path(aliased as-OutFile) and add a-LiteralPathparameter. Existing-OutFilecan be used with current globbing behavior to match a single file using a wildcard. For example, if you have a file called helloworld.txt and you want to overwrite it with the output, you can use-OutFile hello*.ChrisMagnuson commentedon Apr 26, 2019
ThreeFive-O You mention there are work arounds for this, can you add them as a comment?
I am trying to OutFile to a file that has
[1]in the name but I cannot figure out how to escape the[]characters. I tried ` and\but they do not escape the[]characters.vexx32 commentedon Apr 26, 2019
As I recall, Chris, when escaping a path like this you have to double up, or use a literal string. For example:
This is because typically the bare strings in a parameter are treated as expandable strings, which means that the backtick is treated as a PS escape character first and evaluated before being passed to the internals. As a result, you need to escape the escape character so PS's expandable string evaluation doesn't eat it. The other option is to force PS to recognise it as a literal string.
mklement0 commentedon Apr 26, 2019
Rain Sallow (/u/ta11ow) (@vexx32):
While your escaping technique is correct and ensures that the file path is accepted, there is a bug that affects most cmdlets in that they then use the escaped path as a literal path on output-file creation, which means that the
`chars. are unexpectedly retained - see #9475.Therefore, the cumbersome workaround for now is to:
`instances from it.See this Stack Overflow answer for details.
vexx32 commentedon Apr 26, 2019
Well now, that's no good at all! Thanks for the links!