|
1 | 1 | --- |
2 | 2 | description: Explains the concept of scope in PowerShell and shows how to set and change the scope of elements. |
3 | 3 | Locale: en-US |
4 | | -ms.date: 06/07/2024 |
| 4 | +ms.date: 07/22/2024 |
5 | 5 | online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7.2&WT.mc_id=ps-gethelp |
6 | 6 | schema: 2.0.0 |
7 | 7 | title: about Scopes |
@@ -60,7 +60,7 @@ hierarchy of child scopes whose root scope is the global scope. |
60 | 60 | > Modules have their own session state that's linked to the scope in which the |
61 | 61 | > module was imported. All module code runs in a module-specific hierarchy of |
62 | 62 | > scopes that has its own root scope. For more information, see the |
63 | | -> [Modules][02] section of this article. |
| 63 | +> [Modules][03] section of this article. |
64 | 64 |
|
65 | 65 | When a child scope is created, it includes all the aliases and variables that |
66 | 66 | have the **AllScope** option, and some automatic variables. This option is |
@@ -90,7 +90,7 @@ When a reference is made to a variable, alias, or function, PowerShell searches |
90 | 90 | the current scope. If the item isn't found, the parent scope is searched. This |
91 | 91 | search is repeated all they way up to the global scope. If a variable is |
92 | 92 | private in a parent scope, the search through continues through the scope |
93 | | -chain. [Example 4][01] shows the effect of a private variable in a scope |
| 93 | +chain. [Example 4][02] shows the effect of a private variable in a scope |
94 | 94 | search. |
95 | 95 |
|
96 | 96 | ## PowerShell scopes names |
@@ -128,14 +128,14 @@ optional scope modifiers: |
128 | 128 | current scope. |
129 | 129 |
|
130 | 130 | > [!NOTE] |
131 | | - > `private:` isn't a scope. It's an [option][03] that changes the |
| 131 | + > `private:` isn't a scope. It's an [option][04] that changes the |
132 | 132 | > accessibility of an item outside of the scope in which it's defined. |
133 | 133 |
|
134 | 134 | - `script:` - Specifies that the name exists in the **Script** scope. |
135 | 135 | **Script** scope is the nearest ancestor script file's scope or **Global** if |
136 | 136 | there is no nearest ancestor script file. |
137 | 137 | - `using:` - Used to access variables defined in another scope while running |
138 | | - scripts via cmdlets like `Start-Job` and `Invoke-Command`. |
| 138 | + in remote sessions, background jobs, or thread jobs. |
139 | 139 | - `workflow:` - Specifies that the name exists within a workflow. Note: |
140 | 140 | Workflows aren't supported in PowerShell v6 and higher. |
141 | 141 | - `<variable-namespace>` - A modifier created by a PowerShell **PSDrive** |
@@ -266,16 +266,34 @@ Depending on the context, embedded variable values are either independent |
266 | 266 | copies of the data in the caller's scope or references to it. In remote and |
267 | 267 | out-of-process sessions, they're always independent copies. |
268 | 268 |
|
269 | | -For more information, see [about_Remote_Variables][07]. |
| 269 | +For more information, see [about_Remote_Variables][08]. |
270 | 270 |
|
271 | | -In thread sessions, they're passed by reference. This means it's possible to |
272 | | -modify child scope variables in a different thread. To safely modify variables |
273 | | -requires thread synchronization. |
| 271 | +A `$using:` reference only expands to a variable's value. If you want to change |
| 272 | +the value of a variable in the caller's scope, you must have a reference to the |
| 273 | +variable itself. You can create a reference to a variable by getting the |
| 274 | +**PSVariable** instance of the variable. The following example show how to |
| 275 | +create a reference and make changes in a thread job. |
274 | 276 |
|
275 | | -For more information see: |
| 277 | +```powershell |
| 278 | +$Count = 1 |
| 279 | +$refOfCount = Get-Variable Count |
| 280 | +
|
| 281 | +Start-ThreadJob { |
| 282 | + ($using:refOfCount).Value = 2 |
| 283 | +} | Receive-Job -Wait -AutoRemoveJob |
| 284 | +
|
| 285 | +$Count |
| 286 | +``` |
276 | 287 |
|
277 | | -- [Start-ThreadJob][11] |
278 | | -- [ForEach-Object][10] |
| 288 | +```Output |
| 289 | +2 |
| 290 | +``` |
| 291 | + |
| 292 | +> [!NOTE] |
| 293 | +> This is not a thread-safe operation. You can cause data corruption if you try |
| 294 | +> to change the value from multiple threads at the same time. You should use |
| 295 | +> thread-safe data types or synchronization primitives to protect shared data. |
| 296 | +> For more information, see [Thread-Safe collections][01]. |
279 | 297 |
|
280 | 298 | ### Serialization of variable values |
281 | 299 |
|
@@ -387,7 +405,7 @@ Using the call operator is no different than running the script by name. |
387 | 405 | & c:\scripts\sample.ps1 |
388 | 406 | ``` |
389 | 407 |
|
390 | | -You can read more about the call operator in [about_Operators][06]. |
| 408 | +You can read more about the call operator in [about_Operators][07]. |
391 | 409 |
|
392 | 410 | To run the `Sample.ps1` script in the local scope type a dot and a space (`. `) |
393 | 411 | before the path to the script: |
@@ -736,21 +754,23 @@ The `using` scope modifier was introduced in PowerShell 3.0. |
736 | 754 |
|
737 | 755 | ## See also |
738 | 756 |
|
739 | | -- [about_Variables][09] |
740 | | -- [about_Environment_Variables][04] |
741 | | -- [about_Functions][05] |
742 | | -- [about_Script_Blocks][08] |
743 | | -- [Start-ThreadJob][11] |
| 757 | +- [about_Environment_Variables][05] |
| 758 | +- [about_Functions][06] |
| 759 | +- [about_Script_Blocks][09] |
| 760 | +- [about_Variables][10] |
| 761 | +- [ForEach-Object][11] |
| 762 | +- [Start-ThreadJob][12] |
744 | 763 |
|
745 | 764 | <!-- link references --> |
746 | | -[01]: #example-4-creating-a-private-variable |
747 | | -[02]: #modules |
748 | | -[03]: #private-option |
749 | | -[04]: about_Environment_Variables.md |
750 | | -[05]: about_Functions.md |
751 | | -[06]: about_Operators.md |
752 | | -[07]: about_Remote_Variables.md |
753 | | -[08]: about_Script_Blocks.md |
754 | | -[09]: about_Variables.md |
755 | | -[10]: xref:Microsoft.PowerShell.Core.ForEach-Object |
756 | | -[11]: xref:ThreadJob.Start-ThreadJob |
| 765 | +[01]: /dotnet/standard/collections/thread-safe/ |
| 766 | +[02]: #example-4-creating-a-private-variable |
| 767 | +[03]: #modules |
| 768 | +[04]: #private-option |
| 769 | +[05]: about_Environment_Variables.md |
| 770 | +[06]: about_Functions.md |
| 771 | +[07]: about_Operators.md |
| 772 | +[08]: about_Remote_Variables.md |
| 773 | +[09]: about_Script_Blocks.md |
| 774 | +[10]: about_Variables.md |
| 775 | +[11]: xref:Microsoft.PowerShell.Core.ForEach-Object |
| 776 | +[12]: xref:ThreadJob.Start-ThreadJob |
0 commit comments