It would be nice for Out-File to create missing parent folders. Possibly require the -Force flag for this to take effect.
Currently to safely output to a file in a different folder, it's safest to preface your command with a New-Item -Force command.
Adding more detail. To me this is what I would expect to happen with the -Force flag. This could possible be classified as a bug, although I labeled it as an enhancement to be safe.
❯ tree
+ C:\temp
❯ 'example error' | Out-File 'logs/error-log.txt' -Force
Out-File: Could not find a part of the path 'C:\temp\logs\error-log.txt'.
❯ tree
+ C:\temp
❯ 'example error' | Out-File 'logs/error-log.txt' -Force
❯ tree
+ C:\temp
+ logs
- error-log.txt
❯ cat .\logs\error-log.txt
example error
While desired-state functionality is a wonderful thing, the problem is that (a) users have come to expect -Force to have a specific meaning with respect to Out-File (to override a read-only attribute on Windows) and (b) to overload a single flag with multiple, unrelated behaviors is problematic.
It's not as concise, but you can use New-Item's -Force flag:
```powershell
'foo' | Out-File "$(New-Item -Force -Type Directory logs)/error-log.txt"
````
I can understand where overloading the functionality of the Force flag could be problematic. I propose adding a new flag to achieve this functionality. While the statement you provided above works, it hurts readability. I feel like it's reasonable for the end user to expect that Out-File has the ability to create the file (and parent directories) that it's trying to write to. I also feel like this would desired functionality by end users. Of course this is just my opinion, but if others agree, I think this would be a valuable feature to add.
Understood, but at this point I suggest you close _this_ issue, and create a new one, using the "Feature Request/Idea" template, in which you can:
present the proposal along with suggesting a specific (switch) parameter name.
also consider how and which _additional_ file-creating cmdlets - notably Set-Content, which is the faster choice if the input objects already are strings - could be covered.
This thread was created by selecting Feature Request/Idea. My initial comment recommended the Force flag since it matches the functionality of New-Item. I'm not familiar enough with this repository to feel comfortable recommending anything more specific than the desire for Out-File to be capable of generating parent folders. I'm open to suggestions, and I'd happily create a new topic to propose that.
Sorry - I missed that you had indeed used the right template - it was @iSazonov who removed the Issue-Enhancement label and replaced with Issue-Question (which is the default for the _bug_ template).
My sense was that the -Force aspect of your suggestion - which I think we now agree was a dead end - created a _distraction_, so I proposed creating a new "Feature Request/Idea" post - which I still recommend: you can simply _mention_ the aspect of perhaps needing to cover additional cmdlets, soliciting input from others.
Ok, thank you, I will try that. Do you have any suggestion what the flag should be named? I'm not aware or anything with similar functionality to take cues from.
@Joe-Zer0, good question re name for the switch (flag) - I don't think there is a precedent (except in New-Item -Type Directory, where the already ruled-out -Force serves that purpose) and I can't think of anything that strikes the right balance between concision and descriptiveness - something like -CreateDirectoryOnDemand feels clunky.
Perhaps that's an indication that the functionality doesn't really belong there, which is my personal sense.
But I don't want to discourage you from creating a proposal - feel free to create it and see what others say.
-Force isn't required for New-Item -Type Directory (though it is if you're doing -Type File and targeting a file path that contains nonexistent directories).
But yeah, personally I'm kind of feeling this doesn't belong in Out-File itself.
@vexx32, -Force _is_ required if you want _desired-state_ functionality, which is what this issue is about.
That is, if you want New-Item -Type Directory to either create the target directory _on demand_ (and return information about it) or return information about an _existing_ target directory at the specified path, -Force is required.
However, you bring up a good point: with New-Item -Type File (-Type File being the default), creating the parent directory on demand _does_ work; thus, @Joe-Zer0's command could have been rewritten as:
# Replace any existing logs/error-log.txt file
# *or*
# create the /logs/ subdir. on demand an create the 'error-log.txt' file in it.
New-Item -Force 'logs/error-log.txt' -Value 'example error'
I was previously using "if Test-Path" prior to my output redirection. Since this doesn't seem to be getting much traction, I decided to adapt some sample code that @mklement0 posted. It's a bit cleaner that having extra if statements. I also switched back to the redirection operator since I had no use for any Out-File flags.
random command > $(New-Item logs/error-log.txt -Force)
This is a fairly clean method of redirecting output while ensuring the destination file exist. Thanks for both of your help and feedback!
@Joe-Zer0, that's a nice idiom, thanks for sharing.
You can even make it (ever so slightly) shorter by using (...) rather than $(...).
In case you're curious about the difference and when to use which, see this SO answer.
@mklement0
Thanks for that SO link. I've recently been realizing I've been using $() more than I should. That helps me with understanding when it's actually necessary.