How can I write each PDF’s filename into its matching Markdown file?

September 28, 2026 3 answers
Asked by MellowCedar42
I'm using PowerShell to process every PDF in `E:DIY`. For each PDF, I want to create a Markdown file with the same base name, and have the Markdown contain an Obsidian-style link such as `![[filename.pdf]]`, using the actual PDF filename for each file. My current script uses a fixed string, so every Markdown file would contain the literal text `![[filename.pdf]]`. I've also tried properties such as `.FullName`, `.Name`, and `.BaseName`, but I either get an empty value or text like `[[_.fullname]]`. What is the correct way to reference the current file inside the loop and insert its filename into the generated Markdown file? ```powershell $folderPath = "E:DIY" $pdfFiles = Get-ChildItem -Path $folderPath -Filter "*.pdf" foreach ($file in $pdfFiles) { $textFilePath = $file.FullName -replace '.pdf$', '.md' Add-Content -Path $textFilePath -Value $textContent } ```

Answers

BrightOtter19
PowerShell property access doesn’t start with a dot by itself. `.BaseName` only works after an object, such as `$file.BaseName`. For this case, the simplest interpolation is: ```powershell $textContent = "![[${file.Name}]]" ``` However, brace-style formatting is less ambiguous and works reliably: ```powershell $textContent = "![[{0}]]" -f $file.Name ``` Use `$file.FullName` only if you specifically want the complete filesystem path; for an Obsidian wikilink, the filename is usually preferable.
Reply to this answer
QuietMaple7
Use the current loop variable, `$file`, and its `Name` property. Build the text inside the loop so each iteration uses that PDF’s actual name: ```powershell foreach ($file in $pdfFiles) { $textFilePath = [System.IO.Path]::ChangeExtension($file.FullName, '.md') $textContent = "![[{0}]]" -f $file.Name Set-Content -Path $textFilePath -Value $textContent } ``` `$file.Name` includes the `.pdf` extension, which is what the Obsidian link needs. `$file.BaseName` would return the filename without the extension.

MellowCedar42: That makes sense—I was defining `$textContent` before the loop, so it had no current file to refer to. I’ll construct it inside the loop using `$file.Name`.

Reply to this answer
SilverPine88
You can also use a subexpression when interpolating the property: ```powershell $textContent = "![[ $($file.Name) ]]".Replace(' ', '') ``` Or, without the extra cleanup: ```powershell $textContent = "![[$($file.Name)]]" ``` The important part is `$($file.Name)`, not `$.Name` or `_.Name`. Also, use `Set-Content` if each script run should replace the Markdown file rather than append another link to it.
Reply to this answer

Add your answer

Answers are reviewed before publication.

Related Discussions