Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 115 additions & 23 deletions reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
---
description: Describes how to create and use a reference type variable. You can use reference type variables to permit a function to change the value of a variable that is passed to it.
Locale: en-US
ms.date: 08/24/2018
ms.date: 12/12/2024
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-5.1&WT.mc_id=ps-gethelp
schema: 2.0.0
title: about_Ref
---

# about_Ref

## Short description

Describes how to create and use a reference type variable. You can use
reference type variables to permit a function to change the value
of a variable that is passed to it.
Describes how to create and use a reference type variable.

## Long description

You can pass variables to functions *by reference* or *by value*.
You can pass variables to functions _by reference_ or _by value_. When you pass
a variable _by value_, you are passing a copy of the data. When you pass a
variable _by reference_, you are passing a reference to the original value.
This allows the function to change the value of the variable that is passed to
it.Reference types are created using `[ref]`, which is the type accelerator for
the `[System.Management.Automation.PSReference]` type.

When you pass a variable *by value*, you are passing a copy of the data.
The primary purpose of `[ref]` is to enable passing PowerShell variables by
reference to .NET method parameters marked as `ref`, `out`, or `in`. You can
also define your own PowerShell function that take `[ref]` type parameters. In
this usage, `[ref]` is applied to a _variable_, and the resulting `[ref]`
instance can be used to indirectly modify that variable's value.

In the following example, the function changes the value of the variable passed
to it. In PowerShell, integers are value types so they are passed by value.
to it. In PowerShell, integers are value types so they're passed by value.
Therefore, the value of `$var` is unchanged outside the scope of the function.

```powershell
Expand All @@ -41,10 +47,10 @@ $var
```

In the following example, a variable containing a `Hashtable` is passed to a
function. `Hashtable` is an object type so by default it is passed to the
function *by reference*.
function. `Hashtable` is an object type so by default it's passed to the
function _by reference_.

When passing a variable *by reference*, the function can change the data and
When passing a variable _by reference_, the function can change the data and
that change persists after the function executes.

```powershell
Expand All @@ -67,14 +73,14 @@ Test New Text
The function adds a new key-value pair that persists outside of the function's
scope.

### Writing functions to accept reference parameters
## Writing functions to accept reference parameters

You can code your functions to take a parameter as a reference, regardless of
the type of data passed. This requires that you specify the parameters type
as `System.Management.Automation.PSReference`, or `[ref]`.
as `[ref]`.

When using references, you must use the `Value` property of the
`System.Management.Automation.PSReference` type to access your data.
When using references, you must use the `Value` property of the `[ref]` type to
access your data.

```powershell
Function Test([ref]$data)
Expand All @@ -86,7 +92,7 @@ Function Test([ref]$data)
To pass a variable to a parameter that expects a reference, you must type
cast your variable as a reference.

> [!NOTE]
> [!IMPORTANT]
> The brackets and parenthesis are BOTH required.

```powershell
Expand All @@ -99,7 +105,7 @@ $var
3
```

### Passing references to .NET methods
## Passing references to .NET methods

Some .NET methods may require you to pass a variable as a reference. When
the method's definition uses the keywords `in`, `out`, or `ref` on a
Expand Down Expand Up @@ -127,7 +133,7 @@ PS> $number
15
```

### References and scopes
## References and scopes

References allow the value of a variable in the parent scope to be changed
within a child scope.
Expand All @@ -149,10 +155,96 @@ $i = 0;$iRef = 1

Only the reference type's variable was changed.

## Using `[ref]` as a general-purpose object holder

You can also use `[ref]` as a general-purpose object holder. In this usage,
`[ref]` is applied to a _value_ instead of a variable. Typically, the value is
an instance of a _value type_, like a number. In most scenarios you can use a
regular variable or parameter instead. However, this technique is useful in
scenarios where passing an explicit value holder is undesired (for brevity) or
not possible, such as in script-block parameter values.

For example, you can use script-block parameter values to calculate the value
of **NewName** parameter of the `Rename-Item` cmdlet. The `Rename-Item` cmdlet
allows you to pipe items to it. The command run the script block passed to the
**NewName** for each item in the pipeline. The script block run in a child
scope. Modifying a variable in the caller's scope directly won't help and you
can't pass arguments to the script block in this context.

In this example, the script block passed to the **NewName** parameter
increments the value of `$iRef` for each item in the pipeline. The script block
creates a new name by adding a number to the beginning of the filename.

```powershell
$iRef = [ref] 0
Get-ChildItem -File $setPath |
Rename-Item -NewName { '{0} - {1}' -f $iRef.Value++,$_.Name }
```

## Difference between `[ref]` and `[System.Management.Automation.PSReference]`

A reference type variable is created using

Even though `[ref]` is a type accelerator for
`[System.Management.Automation.PSReference]`, they behave differently.

- When you use `[ref]` to cast a variable, PowerShell creates a reference object
that contains a reference to the original instance of the variable.
- When you use `[System.Management.Automation.PSReference]` to cast a variable,
PowerShell creates a reference object that contains a copy of the variable,
rather than a reference to the original instance.

For example, the following script creates a variable `$x` and two reference
objects.

```powershell
PS> $int = 1
PS> $aRef = [ref] $int
PS> $bRef = [System.Management.Automation.PSReference] $int
PS> $int
1
PS> $aRef, $bRef

Value
-----
1
1
```

At this point, both reference objects have the same value as `$int`. By adding
different values to the reference objects, we can see that `$aRef`, which was
created using `[ref]`, is a reference to the original instance of `$int`.
`$bRef`, which was created using `[System.Management.Automation.PSReference]`,
is a copy of the variable.

```powershell
PS> $aRef.Value+=2
PS> $bRef.Value+=5
PS> $int
3
PS> $aRef, $bRef

Value
-----
3
6
```

## See also

- [about_Variables](about_Variables.md)
- [about_Environment_Variables](about_Environment_Variables.md)
- [about_Functions](about_Functions.md)
- [about_Script_Blocks](about_Script_Blocks.md)
- [about_Scopes](about_scopes.md)
- [about_Variables][06]
- [about_Environment_Variables][01]
- [about_Functions][02]
- [about_Script_Blocks][04]
- [about_Scopes][03]
- [about_Type_Accelerators][05]
- [System.Management.Automation.PSReference][07]

<!-- link references -->
[01]: about_Environment_Variables.md
[02]: about_Functions.md
[03]: about_scopes.md
[04]: about_Script_Blocks.md
[05]: about_Type_Accelerators.md
[06]: about_Variables.md
[07]: xref:System.Management.Automation.PSReference
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ Accept wildcard characters: False
### -GroupBy

Formats the output in groups based on a shared property or value. Enter an expression or a property
of the output.
of the output. The **GroupBy** parameter expects that the objects are sorted. Use the `Sort-Object`
cmdlet before using `Format-Custom` to group the objects.

The value of the **GroupBy** parameter can be a new calculated property. The calculated property can
be a script block or a hash table. Valid key-value pairs are:
Expand Down
6 changes: 2 additions & 4 deletions reference/5.1/Microsoft.PowerShell.Utility/Format-List.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ Accept wildcard characters: False
### -GroupBy

Specifies the output in groups based on a shared property or value. Enter an expression or a
property of the output.
property of the output. The **GroupBy** parameter expects that the objects are sorted. Use the
`Sort-Object` cmdlet before using `Format-List` to group the objects.

The value of the **GroupBy** parameter can be a new calculated property. The calculated property can
be a script block or a hash table. Valid key-value pairs are:
Expand Down Expand Up @@ -314,9 +315,6 @@ verb (the `Out` cmdlets), such as `Out-Host` or `Out-File`.
If you do not use a format cmdlet, PowerShell applies that default format for each object that it
displays.

The **GroupBy** parameter assumes that the objects are sorted. Use `Sort-Object` before using
`Format-List` to group the objects.

The **View** parameter lets you specify an alternate format for the table. You can use the views
defined in the `*.format.PS1XML` files in the PowerShell directory, or you can create your own views
in new PS1XML files and use the `Update-FormatData` cmdlet to include them in PowerShell.
Expand Down
6 changes: 2 additions & 4 deletions reference/5.1/Microsoft.PowerShell.Utility/Format-Wide.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ Accept wildcard characters: False
### -GroupBy

Formats the output in groups based on a shared property or value. Enter an expression or a property
of the output.
of the output. The **GroupBy** parameter expects that the objects are sorted. Use the `Sort-Object`
cmdlet before using `Format-Wide` to group the objects.

The value of the **GroupBy** parameter can be a new calculated property. The calculated property can
be a script block or a hash table. Valid key-value pairs are:
Expand Down Expand Up @@ -307,9 +308,6 @@ Windows PowerShell includes the following aliases for `Format-Wide`:

- `fw`

The **GroupBy** parameter assumes that the objects are sorted. Use `Sort-Object` before using
`Format-Custom` to group the objects.

The **View** parameter lets you specify an alternate format for the table. You can use the views
defined in the `*.format.PS1XML` files in the PowerShell directory or you can create your own views
in new PS1XML files and use the `Update-FormatData` cmdlet to include them in PowerShell.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ Accept wildcard characters: False
By default, the `Write-Output` cmdlet always enumerates its output. The **NoEnumerate** parameter
suppresses the default behavior, and prevents `Write-Output` from enumerating output. The
**NoEnumerate** parameter has no effect if the command is wrapped in parentheses, because the
parentheses force enumeration. For example, `(Write-Output 1,2,3)` still enumerates the array.
parentheses force enumeration. For example, `(Write-Output 1,2,3 -NoEnumerate)` still enumerates
the array.

The **NoEnumerate** parameter is only useful within a pipeline. Trying to see the effects of
**NoEnumerate** in the console is problematic because PowerShell adds `Out-Default` to the end of
Expand Down
Loading
Loading