The touch Command in PowerShell (Linux-Compatible)
If you come from Linux/macOS, you probably miss touch: create a file if it doesn’t exist, otherwise update its modified time. PowerShell doesn’t ship with a built-in touch, but you can add one that behaves like the Unix command (including multiple files and wildcards).
This post gives you a practical touch function you can drop into your PowerShell profile, plus examples and notes for edge cases.
What “touch” Should Do
In Unix, touch typically:
- Creates an empty file if it doesn’t exist
- Updates the “Last modified” timestamp if it does exist
- Works with multiple file paths
- Accepts wildcards like
*.txt - Does not print noisy output unless you want it to
We’ll implement that behavior in PowerShell.
Quick One-Off Touch (Single File)
If you only need it once, this is the simplest correct “touch” behavior (create-or-update), without adding newlines to the file:
if (Test-Path .\file.txt) { (Get-Item .\file.txt).LastWriteTime = Get-Date } else { New-Item -ItemType File -Path .\file.txt | Out-Null }
A Linux-Compatible touch Function (Multiple Files + Wildcards)
This function:
- Accepts one or more paths
- Expands wildcards
- Updates timestamps for existing files
- Creates missing files (including parent folders if needed, optional)
- Doesn’t modify file contents
Is quiet by default
function touch { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromRemainingArguments=$true)] [string[]] $Path,
# Optional: create parent directories if missing
[switch] $MakeDirs
)
$now = Get-Date
foreach ($p in $Path) {
# Expand wildcards (e.g. *.txt). If no match, treat as literal.
$expanded = @(Get-ChildItem -LiteralPath $p -ErrorAction SilentlyContinue)
if ($expanded.Count -gt 0) {
foreach ($item in $expanded) {
if ($item.PSIsContainer) {
continue # skip directories (Unix touch can differ; this is safer)
}
$item.LastWriteTime = $now
}
continue
}
# No wildcard matches; treat as a literal file path
if (Test-Path -LiteralPath $p) {
$item = Get-Item -LiteralPath $p
if (-not $item.PSIsContainer) {
$item.LastWriteTime = $now
}
continue
}
# Create the file (optionally create parent folders)
if ($MakeDirs) {
$parent = Split-Path -Parent $p
if ($parent -and -not (Test-Path -LiteralPath $parent)) {
New-Item -ItemType Directory -Path $parent -Force | Out-Null
}
}
New-Item -ItemType File -Path $p -Force | Out-Null
}
}
Examples
Touch one file:
touch .\hello.txt
Touch multiple files:
touch .\a.txt .\b.txt .\c.txt
Touch all .log files in the current directory:
touch *.log
Create a file in a nested folder, creating directories automatically:
touch .\logs\2026\app.log -MakeDirs
Install touch Permanently (Add to Your PowerShell Profile)
PowerShell loads your profile script on startup. Add the function above to your profile file.
Open (or create) your profile:
notepad $PROFILE
Paste the touch function into the file, save, then restart PowerShell.
If profiles are disabled, enable them (Current User):
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Optional: Make It Feel More Like Linux
If you want a shorter alias:
Set-Alias -Name t -Value touch
Add that to the profile too.
Notes and Gotchas
Directories: the function above skips directories. If you want “touch directory updates timestamp” behavior, you can remove the PSIsContainer checks.
Wildcards: PowerShell wildcard expansion is handled via Get-ChildItem. If the wildcard matches nothing, we treat the input as a literal path and create that file (matching common expectations).
No file content changes: unlike "" >> file, this does not append newlines.
–EOF (The Ultimate Computing & Technology Blog) —
737 wordsLast Post: Competitive Programming: Two Simple Tricks in C++ To Make Code Faster
Next Post: Programming is not my wife's thing.