PowerShell Format Numbers and Dates as Strings

Raw object output looks ugly in reports and email bodies — a date like 5/4/2026 8:15:00 AM when you want May 4, 2026, or a size in bytes when you want 1.25 GB. PowerShell format string number date control uses the -f format operator, ToString() method, and Get-Date format strings to produce exactly the output your reports, emails, and logs need. This post covers every common formatting scenario with working examples.
The -f Format Operator
The -f operator formats strings using .NET composite formatting. Position tokens {0}, {1}, etc. map to the arguments after -f. You can include format specifiers inside the braces.
# Basic positional formatting
"{0} has {1} files" -f "C:\Logs", 42
C:\Logs has 42 files
# Reuse positions
"{0} + {0} = {1}" -f 5, 10
5 + 5 = 10
The order of arguments after -f is critical — {0} maps to the first value, {1} to the second. Mixing them up is the most common mistake.
Number Formatting: Currency, Decimal, Percent
Standard format specifiers control how numbers appear. The letter specifies the type, and the optional number specifies precision.
# Currency (locale-specific symbol and separator)
"{0:C}" -f 12345.678 # $12,345.68
"{0:C2}" -f 12345.678 # $12,345.68
# Fixed decimal places
"{0:F2}" -f 3.14159 # 3.14
"{0:F4}" -f 3.14159 # 3.1416
# Percentage (multiplies by 100)
"{0:P1}" -f 0.8523 # 85.2%
"{0:P2}" -f 0.8523 # 85.23%
# Number with thousands separator
"{0:N0}" -f 1234567 # 1,234,567
"{0:N2}" -f 1234567.89 # 1,234,567.89
Padding and Alignment
Control column alignment with a width value after the position number. Positive width right-aligns; negative width left-aligns. Essential for building formatted text tables in console output.
# Right-align in a field of 10 characters
"{0,10}" -f "hello" # " hello"
# Left-align in a field of 10 characters
"{0,-10}" -f "hello" # "hello "
# Build an aligned table without Format-Table
$drives = Get-PSDrive -PSProvider FileSystem | Where-Object Used -gt 0
foreach ($d in $drives) {
"{0,-5} {1,8:N1} GB free" -f $d.Name, ($d.Free / 1GB)
}
C 98.4 GB free
D 812.3 GB free
Get-Date Format Strings
Get-Date accepts a -Format parameter with standard .NET date format specifiers. This is the simplest way to produce a formatted date string.
# Common date formats
Get-Date -Format "yyyy-MM-dd" # 2026-05-04
Get-Date -Format "MM/dd/yyyy" # 05/04/2026
Get-Date -Format "dd MMM yyyy" # 04 May 2026
Get-Date -Format "MMMM d, yyyy" # May 4, 2026
Get-Date -Format "yyyy-MM-dd HH:mm:ss" # 2026-05-04 08:22:11
Get-Date -Format "HH:mm" # 08:22
Get-Date -Format "yyyyMMdd" # 20260504 (good for filenames)
# Use in a filename
$logFile = "C:\Logs\report-$(Get-Date -Format 'yyyyMMdd-HHmmss').csv"
Custom DateTime Format
Format an existing DateTime object — not just the current time — using the -f operator or ToString().
$bootTime = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
# Format with -f operator
"{0:MMMM d, yyyy 'at' h:mm tt}" -f $bootTime
April 28, 2026 at 6:00 AM
# Calculate age and format as a duration
$uptime = (Get-Date) - $bootTime
"{0} days, {1} hours, {2} minutes" -f $uptime.Days, $uptime.Hours, $uptime.Minutes
6 days, 2 hours, 15 minutes
ToString() Method Shortcuts
Every number and DateTime object has a ToString() method that accepts the same format specifiers. This is useful when you’re working with a property directly rather than using -f.
# Format a number directly
(3.14159).ToString("F2") # "3.14"
(1234567.89).ToString("N2") # "1,234,567.89"
(0.8523).ToString("P1") # "85.2%"
# Format a DateTime directly
(Get-Date).ToString("yyyy-MM-dd") # "2026-05-04"
# In an expression inside a string
$size = (Get-Item "C:\Logs\app.log").Length
"File size: $($size.ToString("N0")) bytes"
Common Errors and Fixes
- Format specifier position wrong order:
"{0} wrote {1}" -f $user, $messageworks correctly, but"{1} wrote {0}" -f $user, $messageswaps the values — the result is$message wrote $user. Always match{0}to the first argument,{1}to the second, regardless of how you want them ordered in the output string. - Locale affects decimal separator in number formats: The
:Cand:Nformat specifiers use the current system locale for decimal separators and currency symbols. A machine with a German locale displays1.234,56instead of1,234.56. For locale-independent output (e.g., CSV files to be parsed programmatically), use:F2(fixed-point) and specify the invariant culture:[string]::Format([System.Globalization.CultureInfo]::InvariantCulture, "{0:F2}", 3.14).
Related Cmdlets / See Also
Wrapping Up
The -f operator and Get-Date -Format cover virtually every formatting need you’ll encounter in PowerShell reporting scripts. As a next step, revisit any existing scripts that use manual string concatenation for dates or numbers and replace them with format specifiers — your output will look more professional and the code will be shorter and more readable.


