![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
|
Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
br> br> |
| |||||||
![]() |
| | Thread Tools | Display Modes |
| | #1 (permalink) |
| Guest | Powershell and scope about_scope seems to indicate that when you invoke powershell, a new child scope is created. But it doesn't appear to be a child scope to me, just a new scope. I have no access to a parent scope. $foo = "bar" powershell { write-host $foo } Is this the proper behavior, and is there any way to get the expected behavior instead? |
| | #2 (permalink) |
| Guest | RE: Powershell and scope you can use the scope labels of global, local and script. its explained in about_scope with some examples -- Richard Siddaway Please note that all scripts are supplied "as is" and with no warranty Blog: http://richardsiddaway.spaces.live.com/ PowerShell User Group: http://www.get-psuguk.org.uk "wkempf" wrote: > about_scope seems to indicate that when you invoke powershell, a new child > scope is created. But it doesn't appear to be a child scope to me, just a > new scope. I have no access to a parent scope. > > $foo = "bar" > powershell { write-host $foo } > > Is this the proper behavior, and is there any way to get the expected > behavior instead? |
| | #3 (permalink) |
| Guest | Re: Powershell and scope "wkempf" <wkempf@discussions.microsoft.com> wrote in message news:ED57875B-F98F-4337-A4EB-F32177A0C719@microsoft.com... > about_scope seems to indicate that when you invoke powershell, a new child > scope is created. But it doesn't appear to be a child scope to me, just a > new scope. I have no access to a parent scope. > > $foo = "bar" > powershell { write-host $foo } > > Is this the proper behavior, and is there any way to get the expected > behavior instead? Yep that behavior is expected. By default when you write to a variable that happens to be defined in a parent scope without using any scope qualifier, PowerShell creates a "copy on write" value unique to the current scope. If PowerShell didn't do this then we wind up with essentially global variables everywhere and it would be a nightmare to maintain/debug. To work around this, you can specify a different scope for a variable if you really intend to change the value of the variable in the parent scope. The two options are $script:<varname> means that the variable can be changed at the script level. If you are using dot-sourced functions then that doesn't do you any good. In this case you can use the 'global' scope qualifier to create truly global variables e.g. $global:__PscxCdBackwardStack. If you really, really want finer control over which variable is modified in a parent scope you can use Set-Variable with the -Scope parameter where 1 is the immediate parent (calling) scope, 2 is that parent's parent, etc. However for maintainability purposes I do *not* recommend doing this. -- Keith |
| | #4 (permalink) |
| Guest | Re: Powershell and scope The scope qualifiers don't make any difference here, and even if it did, there would be no effect on the example I posted. Changing the scope qualifier, if powershell created a child scope as the documentation seemed to indicate, would only change whether or not I could modify the variable. The example I posted was attempting only to read it. In any event: PS> $global:foo = "bar" PS> powershell { Write-Host $global:foo } PS> powershell { Write-Host $foo } PS> It seems that invoking powershell creates an entirely new scope, not a child scope. I've found one work around, $env:foo is retained (makes sense). However, that's not exactly a complete work around to my problem. "Keith Hill" wrote: > "wkempf" <wkempf@discussions.microsoft.com> wrote in message > news:ED57875B-F98F-4337-A4EB-F32177A0C719@microsoft.com... > > about_scope seems to indicate that when you invoke powershell, a new child > > scope is created. But it doesn't appear to be a child scope to me, just a > > new scope. I have no access to a parent scope. > > > > $foo = "bar" > > powershell { write-host $foo } > > > > Is this the proper behavior, and is there any way to get the expected > > behavior instead? > > Yep that behavior is expected. By default when you write to a variable that > happens to be defined in a parent scope without using any scope qualifier, > PowerShell creates a "copy on write" value unique to the current scope. If > PowerShell didn't do this then we wind up with essentially global variables > everywhere and it would be a nightmare to maintain/debug. > > To work around this, you can specify a different scope for a variable if you > really intend to change the value of the variable in the parent scope. The > two options are $script:<varname> means that the variable can be changed at > the script level. If you are using dot-sourced functions then that doesn't > do you any good. In this case you can use the 'global' scope qualifier to > create truly global variables e.g. $global:__PscxCdBackwardStack. > > If you really, really want finer control over which variable is modified in > a parent scope you can use Set-Variable with the -Scope parameter where 1 is > the immediate parent (calling) scope, 2 is that parent's parent, etc. > However for maintainability purposes I do *not* recommend doing this. > > -- > Keith > |
| | #5 (permalink) |
| Guest | Re: Powershell and scope On Apr 2, 8:56 am, wkempf <wke...@discussions.microsoft.com> wrote: > The scope qualifiers don't make any difference here, and even if it did, > there would be no effect on the example I posted. Changing the scope > qualifier, if powershell created a child scope as the documentation seemed to > indicate, would only change whether or not I could modify the variable. The > example I posted was attempting only to read it. > > In any event: > > PS> $global:foo = "bar" > PS> powershell { Write-Host $global:foo } > PS> powershell { Write-Host $foo } > PS> > > It seems that invoking powershell creates an entirely new scope, not a child > scope. I've found one work around, $env:foo is retained (makes sense). > However, that's not exactly a complete work around to my problem. > > > > "Keith Hill" wrote: > > "wkempf" <wke...@discussions.microsoft.com> wrote in message > >news:ED57875B-F98F-4337-A4EB-F32177A0C719@microsoft.com... > > > about_scope seems to indicate that when you invoke powershell, a new child > > > scope is created. But it doesn't appear to be a child scope to me, just a > > > new scope. I have no access to a parent scope. > > > > $foo = "bar" > > > powershell { write-host $foo } > > > > Is this the proper behavior, and is there any way to get the expected > > > behavior instead? > > > Yep that behavior is expected. By default when you write to a variable that > > happens to be defined in a parent scope without using any scope qualifier, > > PowerShell creates a "copy on write" value unique to the current scope. If > > PowerShell didn't do this then we wind up with essentially global variables > > everywhere and it would be a nightmare to maintain/debug. > > > To work around this, you can specify a different scope for a variable if you > > really intend to change the value of the variable in the parent scope. The > > two options are $script:<varname> means that the variable can be changed at > > the script level. If you are using dot-sourced functions then that doesn't > > do you any good. In this case you can use the 'global' scope qualifier to > > create truly global variables e.g. $global:__PscxCdBackwardStack. > > > If you really, really want finer control over which variable is modified in > > a parent scope you can use Set-Variable with the -Scope parameter where 1 is > > the immediate parent (calling) scope, 2 is that parent's parent, etc. > > However for maintainability purposes I do *not* recommend doing this. > > > -- > > Keith- Hide quoted text - > > - Show quoted text - Perhaps if you could elaborate on your problem a bit better, we might be able to offer better help? Incidentally, I would have thought it would be obvious to most that invoking a new shell starts with a clean namespace, no? It's a completely new win32 process/appdomain. Applications of any sort rarely share information in this way, apart from clusters of enterprise-level services using named pipes/shared memory. I aint' never heard of a command-line shell cluster before... ;-) - Oisin |
| | #6 (permalink) |
| Guest | Re: Powershell and scope "wkempf" <wkempf@discussions.microsoft.com> wrote in message news:515F015B-0C51-49AE-9D1F-95F318F42588@microsoft.com... > The scope qualifiers don't make any difference here, and even if it did, > there would be no effect on the example I posted. Changing the scope > qualifier, if powershell created a child scope as the documentation seemed > to > indicate, would only change whether or not I could modify the variable. > The > example I posted was attempting only to read it. > > In any event: > > PS> $global:foo = "bar" > PS> powershell { Write-Host $global:foo } > PS> powershell { Write-Host $foo } > PS> > > It seems that invoking powershell creates an entirely new scope, not a > child > scope. I've found one work around, $env:foo is retained (makes sense). > However, that's not exactly a complete work around to my problem. My bad. Yes, using env variables, paremeters passed to the new powershell instance and exporting to clixml (or a generic file) and then reimporting from the clixml in the new shell is about the only I can think of OTTOMH to get info into the new shell. -- Keith |
| | #7 (permalink) |
| Guest | Re: Powershell and scope Obvious, no, for several reasons: Traditional shells have an environment that is shared with sub-shells. Powershell, on the other hand, has a hybrid environment that leads to lots of "not quite what you'd expect" scenarios, including this one. The traditional environment, which you can access via the env logical drive, is shared. The Powershell environment itself, however, is not. Another classic example here is the "current directory" which is not consistent across the boundaries (the current directory in PS is not the same current directory known by other processes, most notably seen when using COM objects). The documentation, as I stated, seemed to indicate that the powershell command would create a child scope. I can see how it can be interpreted multiple ways, so really it's more just unclear than wrong, but still. Any way, back to specifics. What I'm trying to do is create a script that behaves much as Powershell itself behaves, but that sets up a specialized environment for specific tasks. So, invoked by itself I'd wind up in a new shell ready to invoke commands but the environment will have been modified for specific needs. If invoked with a script block, it would set up that specialized environment, run the script block and then exit the sub-shell. I can't fully implement this idea, and one reason for it is the behavior here. "Oisin Grehan" wrote: > On Apr 2, 8:56 am, wkempf <wke...@discussions.microsoft.com> wrote: > > The scope qualifiers don't make any difference here, and even if it did, > > there would be no effect on the example I posted. Changing the scope > > qualifier, if powershell created a child scope as the documentation seemed to > > indicate, would only change whether or not I could modify the variable. The > > example I posted was attempting only to read it. > > > > In any event: > > > > PS> $global:foo = "bar" > > PS> powershell { Write-Host $global:foo } > > PS> powershell { Write-Host $foo } > > PS> > > > > It seems that invoking powershell creates an entirely new scope, not a child > > scope. I've found one work around, $env:foo is retained (makes sense). > > However, that's not exactly a complete work around to my problem. > > > > > > > > "Keith Hill" wrote: > > > "wkempf" <wke...@discussions.microsoft.com> wrote in message > > >news:ED57875B-F98F-4337-A4EB-F32177A0C719@microsoft.com... > > > > about_scope seems to indicate that when you invoke powershell, a new child > > > > scope is created. But it doesn't appear to be a child scope to me, just a > > > > new scope. I have no access to a parent scope. > > > > > > $foo = "bar" > > > > powershell { write-host $foo } > > > > > > Is this the proper behavior, and is there any way to get the expected > > > > behavior instead? > > > > > Yep that behavior is expected. By default when you write to a variable that > > > happens to be defined in a parent scope without using any scope qualifier, > > > PowerShell creates a "copy on write" value unique to the current scope. If > > > PowerShell didn't do this then we wind up with essentially global variables > > > everywhere and it would be a nightmare to maintain/debug. > > > > > To work around this, you can specify a different scope for a variable if you > > > really intend to change the value of the variable in the parent scope. The > > > two options are $script:<varname> means that the variable can be changed at > > > the script level. If you are using dot-sourced functions then that doesn't > > > do you any good. In this case you can use the 'global' scope qualifier to > > > create truly global variables e.g. $global:__PscxCdBackwardStack. > > > > > If you really, really want finer control over which variable is modified in > > > a parent scope you can use Set-Variable with the -Scope parameter where 1 is > > > the immediate parent (calling) scope, 2 is that parent's parent, etc. > > > However for maintainability purposes I do *not* recommend doing this. > > > > > -- > > > Keith- Hide quoted text - > > > > - Show quoted text - > > Perhaps if you could elaborate on your problem a bit better, we might > be able to offer better help? > > Incidentally, I would have thought it would be obvious to most that > invoking a new shell starts with a clean namespace, no? It's a > completely new win32 process/appdomain. Applications of any sort > rarely share information in this way, apart from clusters of > enterprise-level services using named pipes/shared memory. I aint' > never heard of a command-line shell cluster before... ;-) > > - Oisin > > |
| | #8 (permalink) |
| Guest | Re: Powershell and scope "wkempf" <wkempf@discussions.microsoft.com> wrote in message news:E69705D0-7641-4D76-AA21-013969B5BFC3@microsoft.com... > Any way, back to specifics. What I'm trying to do is create a script that > behaves much as Powershell itself behaves, but that sets up a specialized > environment for specific tasks. So, invoked by itself I'd wind up in a > new > shell ready to invoke commands but the environment will have been modified > for specific needs. If invoked with a script block, it would set up that > specialized environment, run the script block and then exit the sub-shell. Take a look at the Export-Console cmdlet. It might help with what you are trying to accomplish. export-console -path SpecialConsole.psc1 powershell.exe -PsConsoleFile SpecialConsole.psc1 -- Keith |
| | #9 (permalink) |
| Guest | Re: Powershell and scope AFAICT, this has diddly squat to do with any PS variables. PS> $global:foo = "bar" PS> export-console test.psc1 PS> powershell -psconsole test.psc1 { write-host $foo } PS> get-content test.psc1 <?xml version="1.0" encoding="utf-8"?> <PSConsoleFile ConsoleSchemaVersion="1.0"> <PSVersion>1.0</PSVersion> <PSSnapIns /> </PSConsoleFile> PS> Looks like the version and snappins are all that's persisted here. "Keith Hill [MVP]" wrote: > "wkempf" <wkempf@discussions.microsoft.com> wrote in message > news:E69705D0-7641-4D76-AA21-013969B5BFC3@microsoft.com... > > Any way, back to specifics. What I'm trying to do is create a script that > > behaves much as Powershell itself behaves, but that sets up a specialized > > environment for specific tasks. So, invoked by itself I'd wind up in a > > new > > shell ready to invoke commands but the environment will have been modified > > for specific needs. If invoked with a script block, it would set up that > > specialized environment, run the script block and then exit the sub-shell. > > Take a look at the Export-Console cmdlet. It might help with what you are > trying to accomplish. > > export-console -path SpecialConsole.psc1 > > powershell.exe -PsConsoleFile SpecialConsole.psc1 > > -- > Keith > > > |
| | #10 (permalink) |
| Guest | Re: Powershell and scope On Apr 2, 10:48 am, wkempf <wke...@discussions.microsoft.com> wrote: > Obvious, no, for several reasons: > > Traditional shells have an environment that is shared with sub-shells. I guess this is where the confusion starts for most beginners to powershell. Psh is anything but traditional. It might try to give that "feel," and I guess its doing that job pretty well if people expect it to behave a certain way and they are misled. > Powershell, on the other hand, has a hybrid environment that leads to lots of > "not quite what you'd expect" scenarios, including this one. The traditional > environment, which you can access via the env logical drive, is shared > The Powershell environment itself, however, is not. Another classic example here > is the "current directory" which is not consistent across the boundaries (the > current directory in PS is not the same current directory known by other > processes, most notably seen when using COM objects). Yes, and this is where I see people trip up most with powershell. Unlike "traditional" shells, there is no implied global location within powershell. The filesystem is a provider, and is treated equally to all other providers it exposes. bash/csh/tcl/ksh, tcl, perl, ruby, python etc all have a single implied current "location" in the shell. A global "current directory" makes sense for them, because there is only one context when it comes to a path. In powershell, there can be multiple current locations, in multiple providers. It tries not to "special case" the filesystem provider (for the most part). I also see this in development of cmdlets, people assume path = filesystem path, that is not always true. > The documentation, as I stated, seemed to indicate that the powershell > command would create a child scope. I can see how it can be interpreted > multiple ways, so really it's more just unclear than wrong, but still. Where exactly did you read this? "powershell" is not a command (a la pscmdlet) provided by the shell itself. If you type "powershell," it is picked up from the env ath and invokes a new powershell.exeprocess, just like any other win32 executable will be picked up. I sympathise nonetheless. Powershell is very like, yet completely unlike any other shell out there. That's what makes it special, and so utterly loveable once you get stuck in. ;-) - Oisin |
| |
| |
![]() |
| Thread Tools | |
| Display Modes | |
| |
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Is this a bug in the scope? | Joel (Jaykul) Bennett | PowerShell | 1 | 2 Weeks Ago 11:33 AM |
| Scope of objects in scripts | Alastair French | PowerShell | 8 | 02-26-2008 02:10 AM |
| Variable scope | Altraf | PowerShell | 6 | 12-13-2007 10:41 AM |
| trap scope | Bob Butler | PowerShell | 9 | 10-27-2007 08:41 PM |
| function scope confusion? | William Stacey [C# MVP] | PowerShell | 1 | 02-05-2007 02:45 PM |