PowerShell Format Numbers and Dates as Strings

PowerShell Format Numbers and Dates as Strings

PowerShell Tips Editor 1 min read
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, $message works correctly, but "{1} wrote {0}" -f $user, $message swaps 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 :C and :N format specifiers use the current system locale for decimal separators and currency symbols. A machine with a German locale displays 1.234,56 instead of 1,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.

Send-Item -To