Create your own
Lesson illustration

Creating and Updating Variables with Common Data Types

Hello again. In the previous lesson, you saw that PowerShell pipelines carry live objects rather than merely the text rendered in the console. Variables give those objects—and simpler values such as names, flags, and counts—a stable name you can reuse, inspect, and update.

For IAM automation, that is foundational. A script may keep a user principal name in a string, a retry count in a number, a safety setting in a Boolean, a list of required groups in an array, and an in-progress identity record in a hash table. This lesson builds those five patterns and clarifies how an update behaves for each.


Variables: naming a value or object

A PowerShell variable begins with $. You create it by assigning a value with =:

$tenantDomain = "contoso.com"

Read the value by writing the variable name:

$tenantDomain

PowerShell creates $tenantDomain on its first assignment. Reusing = later replaces the value:

$tenantDomain = "contoso.com"
$tenantDomain = "fabrikam.com"

$tenantDomain

The result is fabrikam.com.

This is assignment, not a statement that two things are equal in a mathematical sense. In the next lesson, you will use -eq to test equality. For now, remember the distinction:

SyntaxMeaning
$value = "text"Store or replace a value
$value -eq "text"Ask whether two values are equal

A variable can also hold the result of a command. This connects directly to the object-based pipeline model from the previous lesson:

$today = Get-Date

$today.GetType().FullName

$today contains a System.DateTime object, not a formatted date string. Assignment captures the object output that would otherwise have continued to the console.

about_Variables - PowerShell | Microsoft Learn

Read Microsoft Learn’s overview of PowerShell variables to establish the core model: assignment creates or replaces a variable, and a variable can store values ranging from strings to rich command output objects.

In the “Working with variables” section, read assignment and reassignment. Then continue into “Types of variables” and read the types discussion. Focus on the fact that PowerShell determines an untyped variable’s type from its current value.

PowerShell variables are generally loosely typed: a variable name is not permanently tied to one data type.

$value = 12
$value.GetType().FullName

$value = "twelve"
$value.GetType().FullName

The first value is an integer; after reassignment, the same variable name holds a string. This flexibility is convenient for interactive use, but in automation it means names should describe the role of the data accurately. Prefer $retryCount, $userPrincipalName, and $requiredGroups over generic names such as $x or $data.

When a value’s type matters, inspect it rather than relying on its appearance:

$accountLimit = "5"
$accountLimit.GetType().FullName

$accountLimit = 5
$accountLimit.GetType().FullName

The displayed values look identical, but the first is System.String and the second is normally System.Int32. That difference matters when you expect arithmetic, build API request bodies, or validate identity input.


Strings, numbers, and Boolean values

The diagram below is a useful vocabulary map. It includes more types than you need today, but its central message is right: PowerShell can place many kinds of data in variables. Your immediate working set is strings, numbers, Booleans, arrays, and hash tables.

A radial overview of common PowerShell variable types, including String, Integer, Double/Float, Boolean, Array, Hashtable, DateTime, Object, and PSCustomObject. This lesson focuses on the five types most useful for beginning identity scripts: strings, numbers, Booleans, arrays, and hash tables.

Strings: textual identity data

A string is text enclosed in quotation marks:

$userPrincipalName = "jordan.lee@contoso.com"
$department = "Finance"

Use double quotation marks when you want PowerShell to substitute a variable’s value into the text:

$message = "Provisioning account for $userPrincipalName"
$message

Use single quotation marks when you want literal text. Here, PowerShell does not substitute the value of $userPrincipalName:

$literalMessage = 'Provisioning account for $userPrincipalName'
$literalMessage

A string can be updated by replacement or concatenation:

$reportName = "Access Review"
$reportName += " - Finance"

$reportName

The result is:

Access Review - Finance

For simple messages, += is readable. For repeated construction of very large strings, other techniques can be more efficient, but that is not a concern for ordinary IAM messages and identifiers.

Numbers: counts and limits

Whole numbers without quotation marks are normally integers:

$retryCount = 0
$maxFailedAttempts = 5

Numbers containing a decimal point are typically Double values:

$reviewCompletionRate = 87.5

IAM automation often uses integers for counts, pagination positions, retry limits, or the number of accounts processed. Update a number with arithmetic assignment:

$processedCount = 24
$processedCount += 1

$remainingApprovals = 8
$remainingApprovals -= 1

+= is shorthand for “add, then store the result back in the same variable.” Thus:

$processedCount += 1

has the same essential effect as:

$processedCount = $processedCount + 1

You will also encounter ++ for incrementing by one:

$processedCount++

For early scripts, $processedCount += 1 is often clearer because the operation is explicit.

Booleans: true or false settings

A Boolean represents exactly one of two logical values:

$dryRun = $true
$accountEnabled = $false

Use the built-in values $true and $false, not the strings "true" and "false".

$isPrivileged = $true
$isPrivileged.GetType().FullName

This reports System.Boolean.

A Boolean is particularly useful for safety-oriented configuration. For example, a future provisioning script might use $dryRun = $true to calculate and report intended changes without applying them. Importantly, changing a variable does not change an account:

$accountEnabled = $false

This only changes the value stored in your PowerShell session. A later command would have to deliberately use that value to call an identity system and make a real change.

PowerShell 7 Tutorials for Beginners #2 : Variables

Watch “PowerShell 7 Tutorials for Beginners #2: Variables” by JackedProgrammer for a visual introduction to variable declaration, scalar types, Boolean constants, and capturing cmdlet output.

Watch variable basics for declaration syntax, strings, and the distinction between integer and decimal values. Then watch Boolean values, paying particular attention to the built-in $true and $false values. Finish with command capture to reinforce that command output can be stored for later use.

Optional type constraints

Although PowerShell infers types by default, you can declare an intended type before the variable name:

[int]$maxRetries = 3
[string]$environmentName = "Test"
[bool]$dryRun = $true

This asks PowerShell to convert compatible values and reject incompatible ones:

[int]$maxRetries = "5"   # Converts successfully to integer 5

[int]$maxRetries = "five"  # Fails: "five" cannot convert to an integer

Type constraints are useful when a variable has a clear contract, such as a retry limit that must be numeric. They are not required for every variable; use them to make important assumptions explicit rather than as decoration.


Arrays: one variable, an ordered collection

An array stores multiple values in order. In identity work, an array is suitable for a small collection such as required groups, application roles, or target user IDs.

Create an array with comma-separated values:

$requiredGroups = "HR-Portal-Users", "VPN-Users", "Security-Training"

Or use @() to make the collection nature especially clear:

$requiredGroups = @(
    "HR-Portal-Users"
    "VPN-Users"
    "Security-Training"
)

Array positions use zero-based indexes:

$requiredGroups[0]  # HR-Portal-Users
$requiredGroups[1]  # VPN-Users

You can update an existing position:

$requiredGroups[1] = "VPN-Standard-Users"

You can append a group with +=:

$requiredGroups += "MFA-Required"

Afterward, $requiredGroups contains four items. Conceptually, this is an update to the variable’s collection. Technically, standard PowerShell arrays have a fixed size, so PowerShell constructs a new array with the additional item and assigns that new array back to $requiredGroups.

That detail matters later when processing thousands of identities: repeated += operations can be inefficient for large collections. For the small, known lists used in a configuration or a single identity record, the pattern is clear and appropriate.

When you need an empty array, initialize it deliberately:

$groupsToAdd = @()

Then append values as they become known:

$groupsToAdd += "VPN-Standard-Users"
$groupsToAdd += "Security-Training"

Without @(), an initial single string is just a string. Appending another string with += can concatenate text rather than create the group collection you intended.

PowerShell Tutorial 3 : Arrays [Beginners]

Watch “PowerShell Tutorial 3: Arrays [Beginners]” by JackedProgrammer for an illustrated explanation of array creation, zero-based indexing, and appending values.

Watch array setup to see empty-array syntax and why normal arrays are fixed-size. Continue through indexing and additions. Focus on indexing from zero and on the distinction between replacing an indexed item and appending an item.


Hash tables: an identity record organized by named keys

An array answers, “What is item 0?” A hash table answers, “What value belongs to this named key?”

Hash tables are a natural starting structure for a compact identity record or a configuration bundle. Create one with @{}:

$user = @{
    UserPrincipalName = "jordan.lee@contoso.com"
    Department        = "Finance"
    Enabled           = $true
    LicenseSku        = "M365-E3"
}

Each entry has:

  • a key, such as Department;
  • a value, such as "Finance".

Read a value with bracket notation:

$user["UserPrincipalName"]

For simple key names, PowerShell also supports dot notation:

$user.Department

Bracket notation is the more general form. It works when keys contain spaces, punctuation, or variable-based names:

$attributeName = "Department"

$user[$attributeName]

To add a new key or replace an existing value, assign through the key:

$user["Manager"] = "alex.morgan@contoso.com"

$user["Department"] = "Corporate Finance"

$user["Enabled"] = $false

These three lines update the in-memory record only. They do not disable an Entra ID or Active Directory account. Keeping that boundary clear is a basic safety principle: data preparation and external side effects are different steps.

A hash table can contain values of different types, including arrays:

$user["RequiredGroups"] = @(
    "Finance-Users"
    "VPN-Standard-Users"
)

You can then update the nested group list:

$user["RequiredGroups"] += "MFA-Required"

This produces a useful model for an intended account state:

$user

The console may display the entries in an order different from the order you wrote them. Do not use display order as logic; retrieve values by key.

about_Assignment_Operators - PowerShell | Microsoft Learn

Read Microsoft Learn’s assignment-operator reference to consolidate the mechanics behind creating, replacing, and extending variables of different kinds.

In “Using the assignment operator,” read creation versus replacement, then continue through the examples for arrays and hash tables. In “Using compound assignment operators,” focus on string and array updates and the following hash-table examples, especially hashtable addition. Notice that += has different, type-dependent meanings.

You may also add several new keys with a second hash table:

$user += @{
    Country = "US"
    CostCenter = "FIN-042"
}

For changing a known key, prefer direct assignment:

$user["CostCenter"] = "FIN-043"

It communicates intent unambiguously: retrieve the value associated with CostCenter, then replace it.


One small IAM configuration, assembled safely

The following example brings the five variable forms together. It does not contact a directory, change memberships, or write a file; it simply prepares structured values that a later script could validate and use.

[string]$tenantDomain = "contoso.com"
[int]$maxRetries = 3
[bool]$dryRun = $true

$requiredGroups = @(
    "Finance-Users"
    "VPN-Standard-Users"
)

$userRequest = @{
    UserPrincipalName = "jordan.lee@$tenantDomain"
    Department        = "Finance"
    Enabled           = $true
    RequiredGroups    = $requiredGroups
}

# Update scalar values
$maxRetries += 1
$dryRun = $false

# Update hash-table entries
$userRequest["Department"] = "Corporate Finance"
$userRequest["RequiredGroups"] += "MFA-Required"

$userRequest

Trace the state changes:

  1. $tenantDomain holds a string used to construct a user principal name.
  2. $maxRetries is an integer incremented from to .
  3. $dryRun is a Boolean setting changed from $true to $false.
  4. $requiredGroups begins as an array of two strings.
  5. $userRequest is a hash table that combines strings, a Boolean, and the group array.
  6. Updating $userRequest["RequiredGroups"] replaces that hash-table entry with an expanded array.

At this stage, $userRequest is still just local data. This discipline becomes important in IAM work: calculate and inspect the desired state before issuing a command that changes directory state.

A practical inspection routine is:

$userRequest.GetType().FullName
$userRequest["RequiredGroups"].GetType().FullName
$userRequest["RequiredGroups"].Count

The first confirms that the record is a hash table; the second checks the type of its group collection; the third confirms how many group names it currently contains. This is the same inspect-before-assume habit introduced with Get-Member in the prior lesson.


Key takeaways

  • Use = to create a variable or replace its value; the variable begins with $.
  • PowerShell variables can hold live objects as well as strings, integers, Booleans, arrays, and hash tables.
  • Use double-quoted strings for text that should substitute variable values; single-quoted strings preserve text literally.
  • Numbers support arithmetic updates such as += 1; Booleans should use $true and $false.
  • Arrays are ordered, zero-indexed collections. Use @() to initialize a collection clearly, and use indexed assignment or += to update it.
  • Hash tables store named key-value pairs. Use $table["Key"] to retrieve, add, or replace a value.
  • Updating a local variable or hash table does not itself make an IAM change. It only prepares data for a later, explicit operation.

Next, you will use comparison, logical, and membership operators to turn these stored values into identity-related decisions—for example, testing whether an account is enabled, a department matches, or a required group is present.

Can't find a good explanation? Sign up and we'll make it for you

Sign up