Note: Without -Expand parameter, you will be required to make separate Graph API calls to fetch such nested resources.
Here are some practical examples of how to use the -Expand parameter in Microsoft Graph PowerShell module commands:

We’ll explore some of the most useful applications of the Select-object cmdlet, like selecting specific properties from objects, Filtering objects based on conditions, Calculating custom properties, Renaming and sorting properties, Selecting unique objects, and Selecting top/bottom N objects.
In this PowerShell tutorial, I will explain how to expand an array in PowerShell using different methods and examples.
To expand an array in PowerShell, you typically use the += operator to add elements, which effectively creates a new array with the additional elements. For example, $array += ‘new item’ adds ‘new item’ to the end of $array. If you need to expand a property within an object array, you can use the Select-Object cmdlet with the -ExpandProperty parameter.
Expanding an array in PowerShell means to transform a collection of objects so you can work with their properties directly. This is commonly done with the Select-Object cmdlet using the -ExpandProperty parameter.
Here are a few ways to expand an array in PowerShell.
1. Using Select-Object with -ExpandProperty
The Select-Object cmdlet in PowerShell is used to select specific properties of an object or set of objects. When combined with the -ExpandProperty parameter, it allows you to take a property from each object in a collection and return a new array with just the values of that property.
Here’s an example using Get-Process to retrieve a list of processes and then expanding the ProcessName property:
$processNames = Get-Process | Select-Object -ExpandProperty ProcessNameThis will return an array of strings, each one being the name of a process.
After executing the code using PowerShell, you can see the output in the screenshot below:

2. Using ForEach-Object
Another way to expand an array in PowerShell is by using the ForEach-Object cmdlet. This cmdlet allows you to perform an operation on each item within a collection. Here’s how you can use it to achieve similar results to the Select-Object -ExpandProperty:
$processNames = Get-Process | ForEach-Object { $_.ProcessName }3. Using Custom Functions
Here’s a simple custom function to expand an array of objects:
function Expand-ArrayProperty { param( [Parameter(Mandatory = $true)] [array]$Array, [Parameter(Mandatory = $true)] [string]$PropertyName ) $expandedArray = @() foreach ($item in $Array) { $expandedArray += $item.$PropertyName } return $expandedArray
}
# Usage
$processes = Get-Process
$processNames = Expand-ArrayProperty -Array $processes -PropertyName "ProcessName"This function, Expand-ArrayProperty, iterates over each item in the provided array and extracts the specified property, collecting the results into a new array.
Conclusion
Expanding arrays in PowerShell is a powerful technique that allows you to manipulate and access objects’ properties within an array efficiently. Whether you’re using built-in cmdlets like Select-Object with -ExpandProperty, iterating with ForEach-Object, or crafting your custom functions, understanding how to expand arrays will greatly enhance your PowerShell scripting capabilities.
In this PowerShell tutorial, I have explained how to expand an array in PowerShell using various methods like:
- Using Select-Object with -ExpandProperty
- Using ForEach-Object
- Using Custom Functions
You may also like:
Wrapping up
As you can see, Select-Object is a powerful cmdlet in PowerShell that allows you to filter and manipulate data within your scripts. You can significantly enhance your PowerShell scripting capabilities by understanding how to use Select-Object effectively.
What is the difference between Get-Member and Select-Object?
Get-Member is a cmdlet in PowerShell that allows you to view the properties and methods of an object. On the other hand, Select-Object is used to select specific properties from an object or create custom objects with selected properties. While both cmdlets are useful in PowerShell, they serve different purposes and have different functionalities.
How to use select-object with where clause in PowerShell?
What is the difference between select object unique and get-unique?
There is no difference between “select-object -unique” and “Get-Unique” as they both refer to the same concept in programming. Both commands are used to retrieve unique values from a collection or list, removing any duplicates.
What does the ExpandProperty do in PowerShell Select-Object?
ExpandProperty is a parameter in the Select-Object cmdlet in PowerShell. It is used to expand the properties of an object that contains nested properties or collections. When used with Select-Object, ExpandProperty allows you to display the values of the nested properties or collections instead of just the property names. This can be useful when you want to view or manipulate specific data within an object.
How do you get members of an object in PowerShell?
How do you select the first object in PowerShell?
How to use the select-string in PowerShell?
In PowerShell, the Select-String cmdlet is used to search for text patterns (strings) within files or input text. It’s a versatile cmdlet that allows you to perform string searches and extract matching lines from files or text. Here’s how to use Select-String:Select-String -Pattern "error" -Path "C:\Logs\*.log"
How do you select properties from an object in PowerShell?
How to check if an object property has value in PowerShell?
What is the difference between select and select-object?
There is no difference between “select” and “select-object.” They are both PowerShell cmdlets used to select specific properties or columns from an object or output. “Select” is the alias for “select-object,” so they can be used interchangeably.
Select-Object with “Unique” Parameter to Filter Duplicates
In addition to the basic filtering capabilities, Select-Object offers advanced techniques to enhance object filtering. You can use the -Unique parameter that enables you to remove duplicate objects from the result set, ensuring that only distinct objects are returned. Let’s consider the below example with an array variable:
$numbers = 1,2,2,3,3,3,4,5 $numbers | Select-Object -Unique
This will output: 1, 2, 3, 4, 5.
Here is a real-world example to get a unique process list (just display the Name):
Get-Process | Select-Object -Property Name -Unique
Select-Object formatting options
Select-Object can also be used with other formatting cmdlets to control the output format of the data. The most common formatting cmdlets used with Select-Object are Format-Table, Format-List, and Format-Custom.
Format-Table is used to display data in a tabular format. For example, if you want to get the used space, free space, and total space of each drive, and like the results in a friendly table format:
#Get all Drives
$driveInfo = Get-Volume
#Select specific properties from the objects
$refinedDriveInfo = $driveInfo | Select-Object DriveLetter, FileSystemLabel, FileSystemType, @{Name='TotalSizeGB'; Expression={"{0:N2}" -f ($_.Size / 1GB)}}, @{Name='FreeSpaceGB'; Expression={"{0:N2}" -f ($_.SizeRemaining / 1GB)}}
#Format the data in Table format
$refinedDriveInfo | Format-Table -AutoSizeThis output gives you a clean and straightforward view of your disk spaces, making it easier to keep an eye on storage status.
DriveLetter FileSystemLabel FileSystemType TotalSizeGB FreeSpaceGB ----------- --------------- -------------- ----------- ----------- C System NTFS 237.91 175.56 D Data NTFS 931.41 452.03 E Backup NTFS 1862.89 987.64 ... ... ... ... ...
Format-List is used to display data in a list format. Suppose you want a detailed view of your machine’s running services, but you only care about their Name, display names, current status, and start mode.
Get-Service | Select-Object Name, DisplayName, Status, StartType | Format-List
You’ll get a detailed list of services, displaying the mentioned properties in a neat format.

Benefits of Using -Expand Parameter
- Efficiency in Data Retrival: Using the -Expand parameter allows you to retrieve related entities in a single API call rather than making multiple calls to the server. This reduces the total number of requests sent, which can significantly decrease network traffic and improve the overall performance of your application. For instance, retrieving a user and their direct reports or group memberships in one request instead of separate requests for each entity.
- Minimizes API Latency: Every call to an external API introduces latency. By reducing the number of calls with the -Expand parameter, you also reduce the cumulative latency that can occur with multiple API calls. This is particularly advantageous in performance-sensitive applications where response time is critical..
- Consistency in Data Fetching: Using -Expand helps in maintaining consistency in the data fetched. When data from related entities is required, fetching it in a single call ensures that the data is synchronized and reflects the state of the database at the time of the query. This avoids potential discrepancies that might occur when making separate calls at different times.
- Reduces API Quota Usage: Most APIs, including Microsoft Graph, have a quota on the number of calls you can make within a certain period. By using -Expand to retrieve more data per call, you effectively use fewer API calls, which helps in staying within API rate limits and reduces the likelihood of encountering API throttling.
- Optimized Resource Usage: When you fetch data in fewer calls, you also optimize the usage of server and network resources, both on the client-side and the API provider’s side. This can lead to cost savings, especially in cloud environments where resource utilization may directly impact billing.
Related Articles:
Select-Object Syntax and Parameters
Select-Object [-Property <Object[]>] [-InputObject <PSObject[]>] [-ExcludeProperty <Object[]>] [-Unique] [-First <Int32>] [-Skip <Int32>] [-Last <Int32>] [-Index <Int32[]>] [-ExpandProperty <String[]>] [<CommonParameters>]
Here’s a table that outlines the important parameters of the Select-Object cmdlet in PowerShell:
| Parameter | Description |
|---|---|
-Property | Specifies the properties to select. These can be property names or calculated properties using hashtables. |
-ExcludeProperty | Specifies properties that should be excluded from the resulting objects. |
-ExpandProperty | Expands the specified property, showing its individual properties as if they were on the main object. Useful for properties that themselves contain objects. |
-Unique | Returns only unique objects from the array (Identical properties and values). Useful for removing duplicates. |
-InputObject | The -InputObject parameter allows Select-Object to work directly on objects, rather than receiving them through the pipeline input. |
-Last | Selects the last specified number of objects. For example, Select-Object -Last 5 would get the last 5 objects from the input. |
-First | Selects the first specified number of objects. For example, -First 5 would get the first 5 objects from the input. |
-Skip | Skips a specified number of objects before selecting the remaining ones. |
-SkipLast | Skips a specified number of objects at the end of an array. |
The most common parameters used with Select-Object are -Property, -InputObject, and -ExpandProperty. These parameters allow you to select specific properties from an object, filter objects based on certain criteria, and expand properties that contain nested objects.
Select-Object with Where-Object
Another important cmdlet in PowerShell is Where-Object, which is used to filter objects based on specific criteria. The Where-Object is often used in conjunction with Select-Object to create more complex filtering and manipulation of data.
For example, if you need to check all the services that are in the “Stopped” state. Rather than navigating through a sea of irrelevant data, Select-Object can help streamline this:
Get-Service | Where-Object { $_.Status -eq 'Stopped' } | Select-Object DisplayName, StatusIn this example, we use the Where-Object cmdlet to filter objects based on the service status. We then pipe the output to Select-Object, which selects only the DisplayName and Status properties from the objects.
When used together, Select-Object and Where-Object can be used to create powerful data manipulation scripts that can save time and increase efficiency. Filtering (using Where-Object or the where method) reduces the number of objects, while selecting (using Select-Object) reduces the number of properties.
Selecting multiple properties using Select-Object
One of the most common use cases for Select-Object is selecting multiple properties from an object. This is done using the -Property parameter and separating the property names with commas.
Get-Process | Select-Object Name, CPU, ID, WS
In this example, we use the Get-Process cmdlet to retrieve all processes. We then pipe the output to Select-Object, which selects only the Name, CPU, and ID properties from the set of objects.

Table of contents
- Understanding Select-Object in PowerShell
- Select-Object Syntax and Parameters
- PowerShell Select-Object cmdlet: Basic Usage
- Selecting multiple properties using Select-Object
- Adding calculated properties with Select-Object expression
- Select-Object with Where-Object
- Limiting the results with “First” and “Last” parameters
- Using the “ExpandProperty” with Select-Object
- Select-Object with “Unique” Parameter to Filter Duplicates
- The skip parameter in select-object
- Select-Object formatting options: Format-Table and Format-List
- Combining Select-Object with Sort-Object and Group-Object
- Select-Object cmdlet Common Scenarios
- Best Practices for Using Select-Object in PowerShell
Get Group Membership Details
You can download the script here: graph-powershell-script-for-listing-group-memberships.ps1
How the Script Works?
- Retrieve User and Group Memberships:
- Get-MgUser is the cmdlet used to fetch user data from the Microsoft Graph.
- -UserId “9ccc0d2b-ff1f-4d13-9dcf-a42749fd27ba” specifies the unique identifier for the user whose information you want to retrieve.
- -Expand “memberOf” is crucial in this context. The Expand parameter directs the API to include detailed information about related entities—in this case, all the groups (memberOf) the user is part of. Normally, the memberOf data isn’t included in the basic user information fetch and would require a separate request to obtain.
- Check if the User Is Part of Any Groups:
- This checks if the MemberOf property contains any items, indicating that the user is a member of one or more groups.
- Loop Through Each Group and Display Group IDs:
- This loop iterates through each group found in the MemberOf property.
- For each group, the script extracts and outputs the group’s unique identifier (Id).
- Handle Case Where No Group Memberships Exist:
- If the MemberOf property is empty, indicating that the user does not belong to any groups, the script outputs a message stating this fact.
Script Output
PowerShell Select-Object cmdlet
Select-Object allows you to filter and select specific properties of an object. This means you can retrieve only the pieces of data you need while ignoring the rest, which can be incredibly useful when dealing with large datasets. Let’s see how to use the PowerShell Select-Object:
Get-ChildItem | Select-Object FullName
This would return a list of all files and folder’s path in the directory, but only show the path for each item. It can be likened to the SQL SELECT statement, but for PowerShell. Using this cmdlet, you can extract the information you need, filter out unnecessary properties, and even modify or format the displayed output.
Select-Object cmdlet Common Scenarios
To help you get started with Select-Object, here are some examples of common scenarios where it can be useful:
- Selecting specific properties from a data set. Filtering Object Properties is the most frequent use of Select-Object, as it narrows down the properties displayed in the output.
- Limit the Number of Results: To get a subset of the output, use the -First and -Last parameters.
- Skipping Results: You can skip a set of initial results using the -Skip parameter.
- Creating Calculated Properties: You can create custom properties using hashtables, which allow you to present data in a new or more readable way.
- You can use the -Unique parameter to remove duplicates from a list.
- Expanding Nested Properties: If an object has a property that itself contains other objects or properties, you can “flatten” this property using the -ExpandProperty parameter.
Using the “ExpandProperty” with Select-Object
Sometimes, an object may contain nested properties you want to select or manipulate. This can be done using the -ExpandProperty parameter. For example, if you have an object containing a nested property and want to select only that property, you can use the ExpandProperty parameter.
Consider this example: When you retrieve the access control list (ACL) for a file or directory using Get-Acl, you’ll notice the Access property contains several Access Control Entries (ACEs). If you want to view these ACEs separately:
$FileACL = Get-Acl -Path "C:\Temp\AppLog.txt" $FileACL | Select-Object -ExpandProperty Access
In this example, The output would list all the ACEs, showing details about each entry’s identity, permissions, and other related attributes.
Here is another real-world example: Let’s say you have a list of files, and each file has a Directory property, which itself is an object with various properties (like FullName, BaseName, etc.). If you simply want the full directory path for each file, you can use -ExpandProperty with Select-Object.
# Get all files in the C:\temp directory recursively, and select their Directory property $Files = Get-ChildItem -Path "C:\temp" -File -Recurse # Display just the FullName property of the Directory object for each file $Files | Select-Object -ExpandProperty Directory | Select-Object -Property FullName
Best Practices for Using Select-Object in PowerShell
- Always use
Select-Objectas early in the pipeline as possible - Selecting only the necessary properties to minimize the data processed is advisable.
- Use
-ExpandPropertywhen working with complex objects. It is recommended to use the-ExpandPropertyparameter when dealing with nested properties to access the desired values easily. - Avoid using wildcard characters unless necessary.
- Using expressions sparingly and optimizing calculations can significantly improve the performance of your scripts.
- Use
-Firstto work with a smaller data set whenever possible
The skip parameter in select-object
Use the -Skip parameter to skip a certain number of objects from the beginning of a data set. It’s particularly useful when you want to omit a certain number of objects at the beginning of a sequence. Example:
Get-Process | Select-Object -Skip 5 -First 5
You can also combine the -Skip parameter with others like -First to create a more controlled selection. For instance, if you want to skip the first 5 numbers and then select the next 3 numbers:
$numbers = 1..10 $numbers | Select-Object -Skip 5 -First 3
EmployeeID,FirstName,LastName,Department,Salary 101,John,Smith,Finance,55000 102,Alice,Johnson,HR,48000 103,Robert,Doe,IT,60000 104,Susan,Williams,Marketing,52000 105,Michael,Anderson,Sales,58000
Now, if you want to read the contents of this file, but want to skip the first lines as that’s a header. You can use the Get-Content cmdlet in combination with Select-Object and its -Skip parameter. Here’s how you can achieve this with PowerShell:
$Emplyees = Get-Content C:\Data\Employees.txt | Select-Object -Skip 1
Combining Select-Object with Sort-Object and Group-Object
Select-Object can also be combined with other PowerShell cmdlets to perform more complex operations. The most common cmdlets that are used with Select-Object are Sort-Object and Group-Object.
Get-ChildItem -Path "C:\Temp" -File | Sort-Object LastWriteTime -Descending | Select-Object -First 10 Name, LastWriteTime
Group-Object is used to group data based on a specific property. For example, imagine you’re analyzing a directory with multiple file types, and you want to know the count of each file type, ordered by count.
Get-ChildItem -Path "C:\Temp" -File | Group-Object -Property Extension | Sort-Object -Property Count -Descending | Select-Object Name, Count
Get Direct Reports to Manager
Here’s the Graph PowerShell script that fetches the direct reports to a manager with the help of -Expand property
You can download the script here: graph-powershell-script-for-listing-direct-reports.ps1
How the Script Works?
- Retrieve User and Direct Reports:
- Get-MgUser is a cmdlet that fetches user information from Microsoft Graph.
- -UserId “1b3ed1a5-438e-4ce9-9f63-f880991afd3a” specifies the unique identifier of the user you want to query.
- -Expand “directReports” is crucial here. The Expand parameter tells the Microsoft Graph API to not only fetch the primary entity (the user) but also expand and include related entities—in this case, the user’s direct reports. Without using -Expand, you would only receive the primary user’s data, and additional requests would be needed to fetch each direct report.
- Check if Direct Reports Exist:
- This checks if the DirectReports property is populated, indicating that the user has direct reports.
- Loop Through Each Direct Report
- Iterates over each direct report retrieved. For each direct report, it extracts and potentially modifies the display of certain properties like name, email, and job title.
- Extract and Display Properties:
- Each property (name, email, job title) is extracted from the AdditionalProperties dictionary of the direct report.
- It checks if each property is null or empty and replaces missing values with “Not Available” for clearer output.
- Finally, it outputs the details for each direct report.
- Handle No Direct Reports:
- If the user has no direct reports, it outputs an appropriate message indicating this fact.
Script Output
Get User Manager Details
How the Script Works?
- Retrieving User and Manager Details:
- Get-MgUser is a cmdlet from the Microsoft Graph PowerShell SDK, used here to retrieve user information.
- -UserId “9ccc0d2b-ff1f-4d13-9dcf-a42749fd27ba” specifies the unique identifier for the user you want to retrieve information for.
- -Expand “manager” is an important parameter here. The Expand parameter is used to include related entities in the result. In this case, it retrieves the user’s manager information along with the user’s details. Without using -Expand, the manager information would not be included by default and would require a separate request.
- Checking if Manager Exists:
- This condition checks if the Manager property of the user is not null, meaning it checks if the user has a manager assigned.
- Extracting Manager’s Details:
- If the user has a manager, the script extracts the manager’s displayName, mail, and jobTitle from the AdditionalProperties dictionary of the Manager object.
- Handling Null or Missing Properties:
- Each extracted property is checked to see if it is null or empty. If it is, the script replaces the null or empty value with “Not Available”:
- Displaying the Manager’s Details:
- If the user has a manager, the script outputs the manager’s name, email, and job title:
- Handling Users without a Manager:
- If the user does not have a manager ($userWithManager.Manager is null), the script displays a message stating that the user does not have a manager assigned:
Script Output
Understanding Select-Object in PowerShell
In PowerShell, objects are represented as structured data with properties and values. When dealing with a collection of objects, it is often necessary to filter out specific objects based on certain conditions. Object filtering allows you to extract only the required information from a larger dataset, making it easier to work with and process.
Select-Object is a versatile cmdlet that you can use in various ways. It commonly filters data within PowerShell and can also create custom objects and filter objects based on specific criteria, such as numeric or string values.
One of the most important things to understand about Select-Object is that it is a pipeline cmdlet. This means it takes input from a previous cmdlet and passes the output to the next cmdlet in the pipeline.
Adding calculated properties with Select-Object expression
In addition to selecting existing properties, you can use Select-Object to add calculated properties to an object. This is done using the Expressions. Expressions are used to perform calculations and transformations on data within objects.
Get-ChildItem -Path "C:\Temp" -File | Select-Object Name, @{Name='SizeInKB'; Expression={$_.Length / 1KB -as [int]}}Here is another example: Suppose you’d like to append a friendly commentary to the status of each service:
Get-Service | Select-Object DisplayName, Status, @{Name='Comments'; Expression={if ($_.Status -eq 'Running') {'All good!'} else {'Needs attention.'}}}The expression checks the Status of the service and provides a corresponding commentary.
Rename Properties using Select-Object Expressions
If you want to rename a property, you can use the expression:
Get-Process | Select-Object @{Name='ProcessName'; Expression={$_.Name}}This will rename the ‘Name’ property to ‘ProcessName’.
You can also use the Select-Object expressions with the Format operator. E.g., you need to see the drive type, free space, and total size of each storage device.
#Get All Drives
$drives = Get-CimInstance -ClassName Win32_LogicalDisk
#Get Free space and Total size
$drives | Select-Object DeviceID, DriveType, @{Name='FreeSpaceGB'; Expression={"{0:N2}" -f ($_.FreeSpace/1GB)}}, @{Name='TotalSizeGB'; Expression={"{0:N2}" -f ($_.Size/1GB)}} | Format-ListBy leveraging expressions with Select-Object, you can modify the selected properties on the fly, perform calculations, and even create new calculated properties based on existing ones.
Limiting the results with “First” and “Last” parameters
You can limit the results from the output with the -First and -Last parameters and control the number of output objects. Suppose you have an array of numbers and want to select the first three:
$array = 1..10 $array | Select-Object -First 3
Get-ChildItem -Path "C:\Temp" | Sort-Object Length -Descending | Select-Object -First 10
Or you can use multiple select-object cmdlets to get the top 5 processes that take more CPU:
# Sort and pick the First 10 process that consumes More CPU Get-Process | Select-Object Name, CPU, WorkingSet | Sort-Object -Descending CPU | Select-Object -First 10 #Similarly, You can get top 10 process that occupies most memory with: Get-Process | Sort-Object -Property WS -Descending | Select-Object -First 10
Similarly, to get the last 10 objects from the pipeline, use the below:
Get-Process | Select-Object -Property ProcessName, Id, WS -Last 10
You can select properties by name like above, or by index:
Get-Process | Select-Object -Index 0,2
This selects the 1st and 2nd objects returned. Use the index values in a comma-separated list. Indexes begin with 0, where 0 represents the first value and (n-1) represents the last value.


