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
Convert-Path should work with non-existent paths #2993
It seem clear to me that a design mistake was made when Resolve-Path and Convert-Path were created, and they both return only resolved paths (i.e. the path must exist).
The right design would be to have Convert-Path not care if the path exists, and if you care, you use both commands.
Since that ship has sailed, I propose adding a -Unresolved switch to Convert-Path to change it to do what it should have done all along, called GetUnresolvedProviderPathFromPSPath instead of calling GetResolvedProviderPathFromPSPath.
If nobody has a problem with that ... I can send a PR
Opting out of behavior is more typically done with -No* parameters (-NoNewline, -NoProxy, -NoClobber, ... - Get-Module and Invoke-WebRequest/RestMethod are, unfortunately, dissenters and use -Skip*)
TBH, -Skip<Something> and -No<Something> are very close, although have very subtle difference.
-Skip<Something> used in cmdlets ((SkipCertificateCheck, SkipEditionCheck, SkipHeaderValidation, SkipNetworkProfileCheck, SkipCACheck, SkipCNCheck, SkipRevocationCheck) ) is typically for bypassing some check.
-No<Something> used in cmdlets ((NoClobber, NoNewline, NoServiceRestart, NoTypeInformation, NoProxy, NoRecurse, NoQualifier, NoNewWindow, NoNewScope, NoMachineProfile, NoEnumerate, NoEncryption, NoElement, NoCompression, NoWait)) is typically about not taking specific action.
In this case -SkipPathCheck (or maybe -SkipPathResolution or -SkipPathValidation) seems more appropriate.
Thanks, Hemant Mahawar (@HemantMahawar), I see the difference, but I personally don't think it's strong enough to warrant reflection in distinct parameter names.
Case in point: You could equally argue that the requested behavior here is not taking the action of resolving the path.
To put it differently: I think the existing -Skip* parameters should have been named -No* instead to begin with for consistency (though, should we reach a consensus, we could introduce aliases for consistency going forward).
I'm concerned about this -SkipPathValidation parameter name and about what Ilya (@iSazonov) wrote:
... GetResolvedProviderPathFromPSPath resolves glob chars vs GetUnresolvedProviderPathFromPSPath doesn't ... I believe we want GetResolvedProviderPathFromPSPath but internal one with allowNonexistingPaths=true parameter.
I thought we were all on the same page that this would actually not resolve paths ...
we're not (just) skipping validation, we're going to not "resolve" the path to an existing folder -- which means that if we're passed a path with wildcards, we would return a path that still has wildcards in it, right?
I mean, if you won't verify the existence of the file, then you cannot resolve the wildcards, right?
I recently needed path validation to be skipped and also think it would he a great addition to Convert-Path. I'll be happy to raise a PR once I can get the code change ready.
Hi, I was pointed here because of a similar design Issue, so what's now the difference between -No* and -Skip*? When would I use one over the other? Maybe it's because I'm not a native speaker, but all of the examples given back here #2993 (comment) don't really help "solve" that mystery for me. All of these sound just perfectly fine:
NoCertificateCheck, NoEditionCheck, NoHeaderValidation, NoNetworkProfileCheck, NoCACheck, NoCNCheck, NoRevocationCheck, ... also they more clearly indicate being the antonyms to a default behavior. Is it now "best practice" to use these switches instead of using either param([switch]$CertificateCheck=$true) or param([switch]$SkipCertificateCheck=$false)?
The only difference I see is that the -No* ones aren't auto generated for switches right now and -Skip* is often used instead of a default$true-switch that forces a specific feature to be enabled by default. Where as -No is currently used either as the antonym to another switch or boolean-filtering (basically to avoid to query data that would be dropped by an where-objects call right after, basically a "query-time where-object") but not features. Like it'd be function Get-MyAccounts{ param([switch]$NoServiceAccounts) }. Is this the "best practice" now/still?
(Similarly -Not is often used to filter non-boolean data and lists. e.g. Get-WUInstall -NotUpdateID XXXX queries the complement to Get-WUInstall -UpdateID XXXX [and technically those two also only exist to work around not being able to optimize Get-WUInstall | Where-Object UpdateID -eq/ne XXXX at query time]).
[Edit: With the exception of -Skip (by itself and not a suffix) also being used for an amount. But as -Skip 5 is different than -SkipNr 5 it kinda makes sense, at least until we also add -Ignore* into the mix...]
Is there a dedicated issue or proposal for this? It is kinda misplaced within an issue about Convert-Path, I think.
Also I'd like keep posted about this topic and I'd argue for have auto generated No switches for every defined one, that'd remove a bunch of validationscript-blocks :D
(Also there is a 3rd one -Ignore* that similarly shares the same meaning and no clearly stated coding-convention either)
Indeed, I agree that there's no meaningful difference between -No* and -Skip*, and, as I've previously argued, introducing -Skip* parameters was ill-advised to begin with.
In general, switch parameters should never default to $true, as that would contravene user expectations. Thus, opting out of default behaviors should be implemented via -No* switches.
As for auto-generated -No switch variants:
The above implies that negating switches is best done implicitly, by omitting them in invocations.
However, explicit negation is still situationally called for, and PowerShell provides a syntax for that: follow the switch name by : (and optional whitespace) and $false; .e.g., -NoValidation:$false
This is a conceptual necessity for situationally overriding switches whose default value is implied by preference variables, e.g., -Confirm:$false
It is also helpful when argument values are constructed programmatically, notably via splatting.
Sadly, the way this syntax is handled for [switch] parameters that are used to select a parameter set by making them mandatory is likely to lead to broken implementations, including for several built-in cmdlets, as of this writing:
Activity
iSazonov commentedon Jan 13, 2017
Great! Make PR.
I'd only made the switch more descriptive:
-UnresolvePath?megamorf commentedon Jan 21, 2017
I'd suggest something along the lines of -SkipPathCheck similar to the other Skip switches as mentioned in #2006
iSazonov commentedon Jan 21, 2017
Perhaps Keith Hill (@rkeithhill) will again offer a good option.
iSazonov commentedon Oct 31, 2018
Steve Lee (@SteveL-MSFT) Michael Klement (@mklement0) Can we approve the new behavior and parameter?
SteveL-MSFT commentedon Oct 31, 2018
The new behavior behind a switch seems fine. cc Hemant Mahawar (@HemantMahawar) if he has any good suggestions on naming.
mklement0 commentedon Oct 31, 2018
Opting out of behavior is more typically done with
-No*parameters (-NoNewline,-NoProxy,-NoClobber, ... -Get-ModuleandInvoke-WebRequest/RestMethodare, unfortunately, dissenters and use-Skip*)Therefore:
-NoResolve, perhaps?HemantMahawar commentedon Oct 31, 2018
TBH, -Skip
<Something> and -No<Something> are very close, although have very subtle difference.-Skip
<Something> used in cmdlets ((SkipCertificateCheck, SkipEditionCheck, SkipHeaderValidation, SkipNetworkProfileCheck, SkipCACheck, SkipCNCheck, SkipRevocationCheck)) is typically for bypassing some check.-No
<Something> used in cmdlets ((NoClobber, NoNewline, NoServiceRestart, NoTypeInformation, NoProxy, NoRecurse, NoQualifier, NoNewWindow, NoNewScope, NoMachineProfile, NoEnumerate, NoEncryption, NoElement, NoCompression, NoWait)) is typically about not taking specific action.In this case
-SkipPathCheck(or maybe-SkipPathResolutionor-SkipPathValidation) seems more appropriate.mklement0 commentedon Oct 31, 2018
Thanks, Hemant Mahawar (@HemantMahawar), I see the difference, but I personally don't think it's strong enough to warrant reflection in distinct parameter names.
Case in point: You could equally argue that the requested behavior here is not taking the action of resolving the path.
To put it differently: I think the existing
-Skip*parameters should have been named-No*instead to begin with for consistency (though, should we reach a consensus, we could introduce aliases for consistency going forward).mklement0 commentedon Oct 31, 2018
A couple more thoughts:
Nois shorter and less ambiguous thanSkip, which:Import-Cli -Skip <int>,Select-Object -Skip <int> -SkipLast <int> -SkipIndex <int[]>)SteveL-MSFT commentedon Oct 31, 2018
@PowerShell/powershell-committee reviewed this and recommends
-SkipValidation7 remaining items
doctordns commentedon Jun 1, 2022
The Powershell Cmdlet working group reviewed this and agree that adding a switch to skip the path validation is a good idea.
But what should the switch name be? We discussed two alternatives -SkipValidation or -SkipPathValidation.
Comments
SteveL-MSFT commentedon Jun 1, 2022
If there is ever additional validation in the future, we should be more specific, so my preference is
-SkipPathValidationdoctordns commentedon Jun 1, 2022
Having discussed this further, the parameter name should be
-SkipPathValidationJaykul commentedon Jun 3, 2022
I'm concerned about this
-SkipPathValidationparameter name and about what Ilya (@iSazonov) wrote:I thought we were all on the same page that this would actually not resolve paths ...
As I said before:
I mean, if you won't verify the existence of the file, then you cannot resolve the wildcards, right?
danielzgtg commentedon Jun 18, 2023
We could use a more conventional name
-Force, which would make it consistent withSet-ItemArmaanMcleod commentedon Dec 15, 2023
I recently needed path validation to be skipped and also think it would he a great addition to
Convert-Path. I'll be happy to raise a PR once I can get the code change ready.iSazonov commentedon Dec 15, 2023
I don't see conclusion about what new behavior should be. Obviously "glob expansion", "validation" and "existence" are not the same things.
agowa commentedon Mar 26, 2024
Hi, I was pointed here because of a similar design Issue, so what's now the difference between
-No*and-Skip*? When would I use one over the other? Maybe it's because I'm not a native speaker, but all of the examples given back here #2993 (comment) don't really help "solve" that mystery for me. All of these sound just perfectly fine:NoCertificateCheck, NoEditionCheck, NoHeaderValidation, NoNetworkProfileCheck, NoCACheck, NoCNCheck, NoRevocationCheck, ... also they more clearly indicate being the antonyms to a default behavior. Is it now "best practice" to use these switches instead of using either
param([switch]$CertificateCheck=$true)orparam([switch]$SkipCertificateCheck=$false)?The only difference I see is that the
-No*ones aren't auto generated for switches right now and-Skip*is often used instead of a default$true-switch that forces a specific feature to be enabled by default. Where as-Nois currently used either as the antonym to another switch or boolean-filtering (basically to avoid to query data that would be dropped by an where-objects call right after, basically a "query-time where-object") but not features. Like it'd befunction Get-MyAccounts{ param([switch]$NoServiceAccounts) }. Is this the "best practice" now/still?(Similarly
-Notis often used to filter non-boolean data and lists. e.g.Get-WUInstall -NotUpdateID XXXXqueries the complement toGet-WUInstall -UpdateID XXXX[and technically those two also only exist to work around not being able to optimizeGet-WUInstall | Where-Object UpdateID -eq/ne XXXXat query time]).[Edit: With the exception of
-Skip(by itself and not a suffix) also being used for an amount. But as-Skip 5is different than-SkipNr 5it kinda makes sense, at least until we also add-Ignore*into the mix...]Is there a dedicated issue or proposal for this? It is kinda misplaced within an issue about Convert-Path, I think.
Also I'd like keep posted about this topic and I'd argue for have auto generated
Noswitches for every defined one, that'd remove a bunch of validationscript-blocks :D(Also there is a 3rd one
-Ignore*that similarly shares the same meaning and no clearly stated coding-convention either)mklement0 commentedon May 19, 2025
Klaus Frank (@agowa):
Indeed, I agree that there's no meaningful difference between
-No*and-Skip*, and, as I've previously argued, introducing-Skip*parameters was ill-advised to begin with.In general, switch parameters should never default to
$true, as that would contravene user expectations. Thus, opting out of default behaviors should be implemented via-No*switches.As for auto-generated
-Noswitch variants:The above implies that negating switches is best done implicitly, by omitting them in invocations.
However, explicit negation is still situationally called for, and PowerShell provides a syntax for that: follow the switch name by
:(and optional whitespace) and$false; .e.g.,-NoValidation:$false-Confirm:$false[switch]parameters that are used to select a parameter set by making them mandatory is likely to lead to broken implementations, including for several built-in cmdlets, as of this writing:-Switch:$falsethe same as omitting a switch when selecting a parameter set #25027