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
}
```
3 Answers
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.
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.
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.

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`.