'In powershell spawn notepad++ when file to open has spaces in it
$npp = "C:\Program Files\Notepad++\notepad++.exe";
$myfiles = @(
    "C:\bad boys\file1.txt",
    "C:\bad boys\file2.txt",
    "C:\bad boys\file3.txt"
)
foreach ($file in $myfiles) {
    Start-Process -FilePath $npp -ArgumentList "$file" -PassThru  -NoNewWindow | out-null
}
This almost works... except, It doesn't open in notepad++ because it sees the space in the file name and thinks this is where the file path ends... thus, i am unable to open my file list. Any Ideas how to fix? What i get instead is notepad++ asking many times if I want to create the file "C:\bad"
Solution 1:[1]
tl;dr
While Joel Coehoorn's helpful answer provides an effective solution to your Start-Process problem (which stems from the bug detailed below), you can simplify your code to:
foreach ($file in $myfiles) {
  # Note: | Out-Null is a trick that makes calling *GUI* applications
  #       *synchronous* (makes PowerShell wait for them to exit).
  & $npp $file | Out-Null
}
You're seeing a long-standing bug in Start-Process that causes it to blindly space-concatenate its -ArgumentList (-Args) arguments without using required embedded double-quoting for arguments with spaces when forming the single string encoding all arguments that is passed to the target executable behind the scenes.
- See GitHub issue #5576, which also discusses that a fix will require a new parameter so as not to break backward compatibility.
For that reason, the required embedded double-quoting must be performed manually as shown in Joel's answer.
When passing multiple arguments, it is ultimately easier to pass a single string to -ArgumentList with embedded double-quoting as necessary - essentially by formulating a string similar to how you would pass multiple arguments from cmd.exe:
E.g., if you were to pass two file paths with spaces to Notepad++ at once, you would do:
Start-Process -Wait -FilePath $npp -ArgumentList "`"C:\bad boys\file1.txt`" `"C:\bad boys\file2.txt`""
Also note the overall simplification of the Start-Process call:
- Use of - -Waitto ensure synchronous execution (waiting for Notepad++ to exit before continuing).- It looks like this is what you tried to do by combining -PassThruwith piping toOut-Null, but that doesn't actually work, because that only waits forStart-Processitself to exit (which itself - unlike the launched process - executes synchronously anyway).
 
- It looks like this is what you tried to do by combining 
- The omission of the unnecessary - -NoNewWindowparameter, which only applies to starting console applications (in order to prevent opening a new console window); Notepad++ is a GUI application.
Note that the only good reason to use Start-Process here - rather than direct invocation - is the need for synchronous execution: Start-Process -Wait makes launching GUI applications synchronous (too), whereas with direct invocation only console applications execute synchronously.
If you didn't need to wait for Notepad++ to exit, direct invocation would make your quoting headaches would go away, as the required embedded quoting is then automatically performed behind the scenes:[1]
foreach ($file in $myfiles) {
  & $npp $file # OK, even with values with spaces
}
However, the | Out-Null trick can be used effectively in direct invocation to make calling GUI applications synchronous[2], which leads us to the solution at the top:
foreach ($file in $myfiles) {
  & $npp $file | Out-Null  # Wait for Notepad++ to exit.
}
[1] However, up to at least PowerShell 7.2.x, other quoting headaches can still arise, namely with empty-string arguments and arguments whose values contain " chars. - see this answer.
[2] Out-Null automatically makes PowerShell wait for the process in the previous pipeline segment to exit, so as to ensure that all input can be processed - and it does so irrespective of whether the process is a console-subsystem or GUI-subsystem application. Since GUI applications are normally detached from the calling console and therefore produce no output there, Out-Null has no ill effects. In the rare event that a GUI application does explicitly attach to the calling console and produce output there, you can use | Write-Output instead (which also works if there's no output, but is perhaps more confusing).
Solution 2:[2]
Try quotes around the file paths within the string data:
$myfiles = @( 
    "`"C:\bad boys\file.txt`"", 
    "`"C:\bad boys\file2.txt`"",
    "`"C:\bad boys\file3.txt`""
)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | |
| Solution 2 | Joel Coehoorn | 
