Every value in PowerShell is a .NET object, which means every variable carries an underlying data type that defines what operations can be performed on it. PowerShell can infer types automatically, but understanding the common types is essential for writing predictable scripts, handle numeric precision properly, and build structured custom data models.
Core Data Types
PowerShell maps standard programming types to .NET classes using convenient bracketed shortcuts called type accelerators (e.g., [string], [int]).
| Type Accelerator | Underlying .NET Class | Description | Example |
|---|---|---|---|
[string] |
System.String |
Sequential sequence of Unicode characters | "Server-01" |
[char] |
System.Char |
Single 16-bit Unicode character | 'A' |
[int] / [int32] |
System.Int32 |
32-bit signed integer ($-2^31$ to $2^31-1$) | 42 |
[long] / [int64] |
System.Int64 |
64-bit signed integer | 922337203685477580 |
[double] |
System.Double |
64-bit double-precision floating-point | 3.14159 |
[decimal] |
System.Decimal |
128-bit precise financial decimal | 199.99d |
[bool] |
System.Boolean |
Logical truth value ($true or $false) |
$true |
[datetime] |
System.DateTime |
Calendar date and time value | Get-Date |
[array] |
System.Object[] |
Ordered collection of elements | @(1, 2, 3) |
[hashtable] |
System.Collections.Hashtable |
Unordered key-value dictionary | @{ Key = 'Val' } |
String
A string represents text data, enclosed in single or double quotes.
$name = "PowerShell"
$name.GetType().NameStringChar
A char stores a single Unicode character, declared using the [char] type accelerator.
[char]$grade = "A"
$grade.GetType().NameCharInt (Integer)
An integer stores whole numbers without a decimal point.
$count = 42
$count.GetType().NameInt32Long (64-bit Integer)
A long is a 64-bit signed integer, represented by the .NET System.Int64 type. It is useful when an integer value may exceed the range supported by [int].
The [long] and [int64] type accelerators refer to the same underlying .NET type.
$count = [long]922337203685477580
$count.GetType().NameInt64A 32-bit [int] can store values from -2,147,483,648 through 2,147,483,647, while [long] supports the much larger range from -9,223,372,036,854,775,808 through 9,223,372,036,854,775,807.
You can explicitly declare a variable as a [long]:
[long]$fileSize = 5000000000
$fileSize.GetType().NameInt64Double
A double stores floating-point (decimal) numbers.
$price = 19.99
$price.GetType().NameDoubleBoolean
A boolean stores one of two values: $true or $false.
$isEnabled = $true
$isEnabled.GetType().NameBooleanArray
An array is an ordered collection of values, declared using the @() subexpression syntax.
$colors = @("Red", "Green", "Blue")
$colors.GetType().NameObject[]Hashtable
A hashtable stores data as unordered key-value pairs, declared using @{}.
$user = @{ Name = "Tom"; Age = 30 }
$user.GetType().NameHashtableDateTime
A DateTime object represents a specific point in time, typically created with Get-Date.
$today = Get-Date
$today.GetType().NameDateTimeValue Types vs Reference Types
Under the hood, every .NET type used by PowerShell falls into one of two categories: value types or reference types. This distinction affects how variables behave when copied or passed around.
| Category | Behavior | Examples |
|---|---|---|
| Value Type | Stored directly; assigning to a new variable copies the value | Int32, Int64, Double, Boolean, Char, DateTime |
| Reference Type | Stored as a pointer to the actual data; assigning to a new variable copies the reference, not the data | String, Array (Object[]), Hashtable, [PSCustomObject] |
$a = 5
$b = $a
$b = 10
Write-Output "a=$a b=$b"
$arr1 = @(1, 2, 3)
$arr2 = $arr1
$arr2[0] = 99
Write-Output "arr1=$arr1"where:
$b = $acopies the integer value, so changing$bhas no effect on$a.$arr2 = $arr1copies the reference to the same underlying array, so modifying$arr2also changes$arr1.
./value-vs-reference.ps1a=5 b=10
arr1=99 2 3Numeric Literal Suffixes
PowerShell supports special suffixes on numeric literals to control their type or scale without needing an explicit cast.
| Suffix | Meaning | Example | Result |
|---|---|---|---|
l |
Long integer (Int64) |
100l |
100 as Int64 |
d |
Decimal | 199.99d |
199.99 as Decimal |
kb |
Kilobyte multiplier | 2kb |
2048 |
mb |
Megabyte multiplier | 1mb |
1048576 |
gb |
Gigabyte multiplier | 1gb |
1073741824 |
$fileLimit = 5mb
Write-Output $fileLimit5242880The GetType() Method
Every object in PowerShell inherits a .GetType() method, which returns detailed type information, including the full .NET namespace and base type.
(5).GetType() | Format-ListIsPublic : True
IsSerial : True
Name : Int32
BaseType : System.ValueTypewhere:
Nameshows the short type name (Int32).BaseTypeshows the parent .NET class the type derives from.
Type Casting and Conversion
PowerShell allows explicit type casting using square bracket type accelerators, converting a value from one type to another.
$strNumber = "100"
[int]$intNumber = $strNumber
$total = $intNumber + 50
Write-Output $totalwhere:
[int]$intNumber = $strNumberexplicitly converts the string"100"into an integer.- Without the cast, adding a string and a number can produce unexpected string concatenation instead of arithmetic.
./type-casting.ps1150You can also use the .NET conversion methods or the -as operator for safer, non-throwing conversions:
$value = "42" -as [int]
$value.GetType().NameInt32Introduction to [PSCustomObject]
A [PSCustomObject] is a lightweight, structured object type used to group related properties together, similar to a "record" or "struct" in other languages. It's the preferred way to build custom data structures in PowerShell.
$employee = [PSCustomObject]@{
Name = "Jamie"
Department = "IT"
HireDate = Get-Date "2026-01-10"
}
$employeewhere:
[PSCustomObject]@{ ... }converts a hashtable literal into a structured, ordered object.- Each key becomes a named property accessible via dot notation (
$employee.Name).
./custom-object.ps1Name Department HireDate
---- ---------- --------
Jamie IT 1/10/2026 12:00:00 AM