diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md index 8116e6d81857..289ead3f34fe 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md @@ -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 @@ -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 @@ -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) @@ -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 @@ -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 @@ -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. @@ -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] + + +[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 diff --git a/reference/5.1/Microsoft.PowerShell.Utility/Format-Custom.md b/reference/5.1/Microsoft.PowerShell.Utility/Format-Custom.md index 8a323440ca91..246589dd333f 100644 --- a/reference/5.1/Microsoft.PowerShell.Utility/Format-Custom.md +++ b/reference/5.1/Microsoft.PowerShell.Utility/Format-Custom.md @@ -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: diff --git a/reference/5.1/Microsoft.PowerShell.Utility/Format-List.md b/reference/5.1/Microsoft.PowerShell.Utility/Format-List.md index c8a4c5d0c188..cd465a6ad572 100644 --- a/reference/5.1/Microsoft.PowerShell.Utility/Format-List.md +++ b/reference/5.1/Microsoft.PowerShell.Utility/Format-List.md @@ -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: @@ -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. diff --git a/reference/5.1/Microsoft.PowerShell.Utility/Format-Wide.md b/reference/5.1/Microsoft.PowerShell.Utility/Format-Wide.md index 620ce2b4aa8b..3a09f54500b5 100644 --- a/reference/5.1/Microsoft.PowerShell.Utility/Format-Wide.md +++ b/reference/5.1/Microsoft.PowerShell.Utility/Format-Wide.md @@ -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: @@ -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. diff --git a/reference/5.1/Microsoft.PowerShell.Utility/Write-Output.md b/reference/5.1/Microsoft.PowerShell.Utility/Write-Output.md index 5946fd17c381..4ec049a0680b 100644 --- a/reference/5.1/Microsoft.PowerShell.Utility/Write-Output.md +++ b/reference/5.1/Microsoft.PowerShell.Utility/Write-Output.md @@ -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 diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Ref.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Ref.md index acbfbb151fc4..f0c4227c144a 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Ref.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Ref.md @@ -1,7 +1,7 @@ --- 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-7.4&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Ref @@ -9,18 +9,26 @@ 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 @@ -39,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 @@ -65,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) @@ -84,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 @@ -97,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 @@ -125,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. @@ -147,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] + + +[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 diff --git a/reference/7.4/Microsoft.PowerShell.Utility/Format-Custom.md b/reference/7.4/Microsoft.PowerShell.Utility/Format-Custom.md index bde248c70bb6..7fdaf99c54dd 100644 --- a/reference/7.4/Microsoft.PowerShell.Utility/Format-Custom.md +++ b/reference/7.4/Microsoft.PowerShell.Utility/Format-Custom.md @@ -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: diff --git a/reference/7.4/Microsoft.PowerShell.Utility/Format-List.md b/reference/7.4/Microsoft.PowerShell.Utility/Format-List.md index 3cf5e282d8e6..732ab5645998 100644 --- a/reference/7.4/Microsoft.PowerShell.Utility/Format-List.md +++ b/reference/7.4/Microsoft.PowerShell.Utility/Format-List.md @@ -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: @@ -315,9 +316,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. diff --git a/reference/7.4/Microsoft.PowerShell.Utility/Format-Wide.md b/reference/7.4/Microsoft.PowerShell.Utility/Format-Wide.md index a2f55895f19f..7f96672c35f0 100644 --- a/reference/7.4/Microsoft.PowerShell.Utility/Format-Wide.md +++ b/reference/7.4/Microsoft.PowerShell.Utility/Format-Wide.md @@ -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: @@ -308,9 +309,6 @@ PowerShell includes the following aliases for `Format-Wide`: - All platforms: - `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. diff --git a/reference/7.4/Microsoft.PowerShell.Utility/Write-Output.md b/reference/7.4/Microsoft.PowerShell.Utility/Write-Output.md index e46de77d7700..3a9fd7dcbd28 100644 --- a/reference/7.4/Microsoft.PowerShell.Utility/Write-Output.md +++ b/reference/7.4/Microsoft.PowerShell.Utility/Write-Output.md @@ -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 diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Ref.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Ref.md index 8fcfc9f73b2c..8bf41acd8b0b 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Ref.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Ref.md @@ -1,7 +1,7 @@ --- 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-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Ref @@ -10,18 +10,25 @@ title: 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 @@ -40,7 +47,7 @@ $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. `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 @@ -66,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) @@ -85,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 @@ -98,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 @@ -126,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. @@ -148,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] + + +[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 diff --git a/reference/7.5/Microsoft.PowerShell.Utility/Format-Custom.md b/reference/7.5/Microsoft.PowerShell.Utility/Format-Custom.md index 1bbb19b4ff76..0fe5ee3f95db 100644 --- a/reference/7.5/Microsoft.PowerShell.Utility/Format-Custom.md +++ b/reference/7.5/Microsoft.PowerShell.Utility/Format-Custom.md @@ -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: diff --git a/reference/7.5/Microsoft.PowerShell.Utility/Format-List.md b/reference/7.5/Microsoft.PowerShell.Utility/Format-List.md index 4547a7bb7317..a6434552ca82 100644 --- a/reference/7.5/Microsoft.PowerShell.Utility/Format-List.md +++ b/reference/7.5/Microsoft.PowerShell.Utility/Format-List.md @@ -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: @@ -315,9 +316,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. diff --git a/reference/7.5/Microsoft.PowerShell.Utility/Format-Wide.md b/reference/7.5/Microsoft.PowerShell.Utility/Format-Wide.md index c23aca8a3832..a5b65e46b479 100644 --- a/reference/7.5/Microsoft.PowerShell.Utility/Format-Wide.md +++ b/reference/7.5/Microsoft.PowerShell.Utility/Format-Wide.md @@ -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: @@ -308,9 +309,6 @@ PowerShell includes the following aliases for `Format-Wide`: - All platforms: - `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. diff --git a/reference/7.5/Microsoft.PowerShell.Utility/Write-Output.md b/reference/7.5/Microsoft.PowerShell.Utility/Write-Output.md index db346ad3925b..45f4537f80e4 100644 --- a/reference/7.5/Microsoft.PowerShell.Utility/Write-Output.md +++ b/reference/7.5/Microsoft.PowerShell.Utility/Write-Output.md @@ -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 diff --git a/reference/docs-conceptual/install/Installing-PowerShell-on-Windows.md b/reference/docs-conceptual/install/Installing-PowerShell-on-Windows.md index 67f2cf448fe1..17c50326236d 100644 --- a/reference/docs-conceptual/install/Installing-PowerShell-on-Windows.md +++ b/reference/docs-conceptual/install/Installing-PowerShell-on-Windows.md @@ -1,6 +1,6 @@ --- description: Information about installing PowerShell on Windows -ms.date: 11/18/2024 +ms.date: 12/12/2024 title: Installing PowerShell on Windows --- # Installing PowerShell on Windows @@ -261,7 +261,7 @@ If there is an available upgrade, the output indicates the latest available vers > [!NOTE] > When upgrading, PowerShell won't upgrade from an LTS version to a non-LTS version. It only -> upgrades to the latest version of LTS, for example, from 7.2.3 to 7.2.24. To upgrade from an +> upgrades to the latest version of LTS, for example, from 7.4.3 to 7.4.6. To upgrade from an > LTS release to a newer stable version or the next LTS, you need to install the new version with > the MSI for that release. > diff --git a/reference/docs-conceptual/install/Installing-PowerShell-on-macOS.md b/reference/docs-conceptual/install/Installing-PowerShell-on-macOS.md index 30a85532a2b1..d70bc591ca46 100644 --- a/reference/docs-conceptual/install/Installing-PowerShell-on-macOS.md +++ b/reference/docs-conceptual/install/Installing-PowerShell-on-macOS.md @@ -1,6 +1,6 @@ --- description: Information about installing PowerShell on macOS -ms.date: 11/18/2024 +ms.date: 12/12/2024 title: Installing PowerShell on macOS --- @@ -119,10 +119,7 @@ are: - PowerShell 7.4 - x64 processors - [powershell-7.4.6-osx-x64.pkg][20] - Arm64 processors - [powershell-7.4.6-osx-arm64.pkg][18] -- PowerShell 7.2 (LTS) - - x64 processors - [powershell-7.2.24-osx-x64.pkg][16] - - Arm64 processors - [powershell-7.2.24-osx-arm64.pkg][14] -- PowerShell 7.5-preview +- PowerShell 7.5-rc.1 - x64 processors - [powershell-7.5.0-rc.1-osx-x64.pkg][24] - Arm64 processors - [powershell-7.5.0-rc.1-arm64.pkg][22] @@ -191,9 +188,6 @@ current versions are: - PowerShell 7.4 (LTS) - x64 processors - [powershell-7.4.6-osx-x64.tar.gz][21] - Arm64 processors - [powershell-7.4.6-osx-arm64.tar.gz][19] -- PowerShell 7.2 (LTS) - - x64 processors - [powershell-7.2.24-osx-x64.tar.gz][17] - - Arm64 processors - [powershell-7.2.24-osx-arm64.tar.gz][15] - PowerShell 7.5-preview - x64 processors - [powershell-7.5.0-rc.1-osx-x64.tar.gz][25] - Arm64 processors - [powershell-7.5.0-rc.1-osx-arm64.tar.gz][23] @@ -282,10 +276,6 @@ support those methods. [11]: https://docs.brew.sh/Manpage#link-ln-options-formula [12]: https://github.com/Homebrew [13]: https://github.com/Homebrew/homebrew-cask -[14]: https://github.com/PowerShell/PowerShell/releases/download/v7.2.24/powershell-7.2.24-osx-arm64.pkg -[15]: https://github.com/PowerShell/PowerShell/releases/download/v7.2.24/powershell-7.2.24-osx-arm64.tar.gz -[16]: https://github.com/PowerShell/PowerShell/releases/download/v7.2.24/powershell-7.2.24-osx-x64.pkg -[17]: https://github.com/PowerShell/PowerShell/releases/download/v7.2.24/powershell-7.2.24-osx-x64.tar.gz [18]: https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-osx-arm64.pkg [19]: https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-osx-arm64.tar.gz [20]: https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-osx-x64.pkg diff --git a/reference/docs-conceptual/install/PowerShell-on-ARM.md b/reference/docs-conceptual/install/PowerShell-on-ARM.md index 747f6a47d7bc..dc73f9f6707c 100644 --- a/reference/docs-conceptual/install/PowerShell-on-ARM.md +++ b/reference/docs-conceptual/install/PowerShell-on-ARM.md @@ -27,20 +27,6 @@ Arm versions of PowerShell 7.4 can be installed on the following platforms: Support is based on the [.NET 8.0 Supported OS Lifecycle Policy][03]. -## PowerShell 7.2 - -Arm versions of PowerShell 7.2 can be installed on the following platforms: - -| OS | Architectures | Lifecycle | -| -------------------------------- | ------------- | -------------------------------------- | -| Windows 11 Client Version 22000+ | Arm64 | [Windows][05] | -| Windows 10 Client Version 1607+ | Arm64 | [Windows][05] | -| macOS | Arm64 | [macOS][04] | -| Raspberry Pi OS (Debian 12) | Arm32 | [Raspberry Pi OS][08] and [Debian][06] | -| Ubuntu 22.04, 20.04 | Arm32 | [Ubuntu][07] | - -Support is based on the [.NET 6.0 Supported OS Lifecycle Policy][02]. - ## Installing PowerShell on Arm-based systems For installation instructions, see the following articles: @@ -65,7 +51,6 @@ Raspberry Pi [01]: community-support.md#raspberry-pi-os -[02]: https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md [03]: https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md [04]: https://support.apple.com/macos [05]: https://support.microsoft.com/help/13853/windows-lifecycle-fact-sheet diff --git a/reference/docs-conceptual/install/install-alpine.md b/reference/docs-conceptual/install/install-alpine.md index 899839313ee7..f223bd1672e4 100644 --- a/reference/docs-conceptual/install/install-alpine.md +++ b/reference/docs-conceptual/install/install-alpine.md @@ -1,6 +1,6 @@ --- description: Information about installing PowerShell on Alpine Linux -ms.date: 11/18/2024 +ms.date: 12/12/2024 title: Installing PowerShell on Alpine Linux --- # Installing PowerShell on Alpine Linux @@ -21,7 +21,6 @@ Installation on Alpine is based on downloading tar.gz package from the [releases to the package depends on the version of PowerShell you want to install. - PowerShell 7.4.6 - `https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-linux-musl-x64.tar.gz` -- PowerShell 7.2.24 - `https://github.com/PowerShell/PowerShell/releases/download/v7.2.24/powershell-7.2.24-linux-alpine-x64.tar.gz` - PowerShell 7.5.0-rc.1 - `https://github.com/PowerShell/PowerShell/releases/download/v7.5.0-rc.1/powershell-7.5.0-rc.1-linux-musl-x64.tar.gz` Then, in the terminal, execute the following shell commands to install PowerShell 7.4: diff --git a/reference/docs-conceptual/install/install-debian.md b/reference/docs-conceptual/install/install-debian.md index 234043cc669a..4a9639f1d871 100644 --- a/reference/docs-conceptual/install/install-debian.md +++ b/reference/docs-conceptual/install/install-debian.md @@ -1,6 +1,6 @@ --- description: Information about installing PowerShell on Debian Linux -ms.date: 11/18/2024 +ms.date: 12/12/2024 title: Installing PowerShell on Debian --- # Installing PowerShell on Debian @@ -17,7 +17,7 @@ All packages are available on our GitHub [releases][02] page. Before installing, Debian uses APT (Advanced Package Tool) as a package manager. -## Installation on Debian 10 or 11 via the Package Repository +## Installation on Debian 11 or 12 via the Package Repository Microsoft builds and supports a variety of software products for Linux systems and makes them available via Linux packaging clients (apt, dnf, yum, etc). These Linux software packages are hosted @@ -71,8 +71,6 @@ The link to the current version is: - PowerShell 7.4 (LTS) universal package for supported versions of Debian - `https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell_7.4.6-1.deb_amd64.deb` -- PowerShell 7.2 (LTS) universal package for supported versions of Debian - - `https://github.com/PowerShell/PowerShell/releases/download/v7.2.24/powershell_7.2.24-1.deb_amd64.deb` - PowerShell 7.5-preview universal package for supported versions of Debian - `https://github.com/PowerShell/PowerShell/releases/download/v7.5.0-rc.1/powershell-preview_7.5.0-rc.1-1.deb_amd64.deb` diff --git a/reference/docs-conceptual/install/install-rhel.md b/reference/docs-conceptual/install/install-rhel.md index e2bb23650e87..5c183ea1c0d8 100644 --- a/reference/docs-conceptual/install/install-rhel.md +++ b/reference/docs-conceptual/install/install-rhel.md @@ -1,6 +1,6 @@ --- description: Information about installing PowerShell on Red Hat Enterprise Linux (RHEL) -ms.date: 11/18/2024 +ms.date: 12/12/2024 title: Installing PowerShell on Red Hat Enterprise Linux (RHEL) --- # Installing PowerShell on Red Hat Enterprise Linux (RHEL) @@ -35,9 +35,9 @@ Installing PowerShell from PMC is the preferred method of installation. # Get version of RHEL source /etc/os-release -if [ $(bc<<<"$VERSION_ID < 8") = 1 ] +if [ ${VERSION_ID%.*} -lt 8 ] then majorver=7 -elif [ $(bc<<<"$VERSION_ID < 9") = 1 ] +elif [ ${VERSION_ID%.*} -lt 9 ] then majorver=8 else majorver=9 fi @@ -51,19 +51,10 @@ sudo rpm -i packages-microsoft-prod.rpm # Delete the downloaded package after installing rm packages-microsoft-prod.rpm -# RHEL 7.x uses yum and RHEL 8+ uses dnf -if [ $(bc<<<"$majorver < 8") ] -then - # Update package index files - sudo yum update - # Install PowerShell - sudo yum install powershell -y -else - # Update package index files - sudo dnf update - # Install PowerShell - sudo dnf install powershell -y -fi +# Update package index files +sudo dnf update +# Install PowerShell +sudo dnf install powershell -y ``` ## Installation via direct download @@ -75,8 +66,6 @@ The link to the current version is: - PowerShell 7.4.6 universal package for supported versions of RHEL - `https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-1.rh.x86_64.rpm` -- PowerShell 7.2.24 universal package for supported versions of RHEL - - `https://github.com/PowerShell/PowerShell/releases/download/v7.2.24/powershell-7.2.24-1.rh.x86_64.rpm` - PowerShell 7.5.0-rc.1 universal package for supported versions of RHEL - `https://github.com/PowerShell/PowerShell/releases/download/v7.5.0-rc.1/powershell-preview-7.5.0_preview.2-1.rh.x86_64.rpm` diff --git a/reference/docs-conceptual/install/install-ubuntu.md b/reference/docs-conceptual/install/install-ubuntu.md index 0123836ed16f..9132352ccd0d 100644 --- a/reference/docs-conceptual/install/install-ubuntu.md +++ b/reference/docs-conceptual/install/install-ubuntu.md @@ -1,6 +1,6 @@ --- description: Information about installing PowerShell on Ubuntu -ms.date: 11/18/2024 +ms.date: 12/12/2024 title: Installing PowerShell on Ubuntu --- # Installing PowerShell on Ubuntu @@ -83,8 +83,6 @@ The link to the current version is: - PowerShell 7.4 (LTS) universal package for supported versions of Ubuntu - `https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell_7.4.6-1.deb_amd64.deb` -- PowerShell 7.2 (LTS) universal package for supported versions of Ubuntu - - `https://github.com/PowerShell/PowerShell/releases/download/v7.2.24/powershell_7.2.24-1.deb_amd64.deb` - PowerShell 7.5.0-rc.1 universal package for supported versions of Ubuntu - `https://github.com/PowerShell/PowerShell/releases/download/v7.5.0-rc.1/powershell-preview_7.5.0-rc.1-1.deb_amd64.deb` diff --git a/reference/includes/alpine-support.md b/reference/includes/alpine-support.md index 5f988dfdd49f..82f8dbfe1fbf 100644 --- a/reference/includes/alpine-support.md +++ b/reference/includes/alpine-support.md @@ -1,7 +1,7 @@ --- author: sdwheeler ms.author: sewhee -ms.date: 11/02/2024 +ms.date: 12/12/2024 ms.topic: include --- @@ -11,9 +11,9 @@ Microsoft supports PowerShell until [PowerShell reaches end-of-support][lifecycl Docker images containing PowerShell 7.4 and PowerShell 7.5-preview for x64 are available from the [Microsoft Artifact Registry][mcr] for the following versions of Alpine: -- Alpine 3.17 - OS support ends on 2024-11-22 +- Alpine 3.20 - OS support ends on 2026-04-01 -Docker images of PowerShell aren't available for Alpine 3.18, 3.19, and 3.20. +Docker images of PowerShell aren't available for Alpine 3.21. > [!IMPORTANT] > The Docker images are built from official operating system (OS) images provide by the OS