I was helping someone with a profile script. The script is supposed to connect to a remote Exchange 2010 server using PowerShell v2.0 when it is launched.
The script had a function which is called upon when profile is loaded. The function looked like the following:
function connect-remotely() { if ($server) { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$server/PowerShell/ -Authentication Kerberos Import-PSSession $Session write-warning 'Do not forget to run Remove-PSSession $Session' } else { $server = read-host "Server name" connect-remotely $server } } |
The $session variable in this instance gets created and populated within the function. The problem, however, is not visible until a bit later. When we were done with our remote session, we tried to remove session using Remove-PSSession $session but encountered an error which indicated that $session has null value.
Why did that happen? That’s where I needed to understand how scopes work. The PowerShell session is created when we launch PowerShell. When the function is executed, a child scope is created. The $session variable is created within child scope. All is fine until after the function completes execution and exits. At this time, $session variable value becomes null since the scope in which it was created is no longer applicable.
But wait, don’t we need the object stored in that variable to remove session successfully? We sure do. So how do we address this?
This can be accomplished using one of the two ways:
1. Define the variable as global. This will make the variable available in all scopes including the one created by function and the parent scopes. Here’s how you can do it:
$Global:Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$server/PowerShell/ -Authentication Kerberos |
2. Second option (I like it better) is to define scope. I used New-Variable as describe below when creating $session within function and scoping it to value of 1:
New-Variable -Name Session -Value (New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$server/PowerShell/ -Authentication Kerberos) -Scope 1 |
When you scope any variable, value 0 means the scope in which it was created. 1 means parent scope, 2 is grand parent and so on. By defining scope of 1, I made the variable available to parent scope of the function which is where I was running Remove-PSSession. As anyone can guess, both methods allowed me to successfully remove session as the variable $session stayed behind populated instead of becoming null.
Hopefully this will help you understand how scope can help in certain situations. For better understanding of scopes, head out to TechNet as it contains lot more information about scopes which is not in scope of this post… get it? 😉