Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Calling powershell script and keeping obtained variable in the 'main' script

Posted on 2016-11-03
6
Medium Priority
?
317 Views
Last Modified: 2016-11-04
I have been using PowerShell to automate some administrative functions.  A lot of the scripts contain common code and I would like to put this common code into its own separate script (process) The issue I am having, which is understandable, is that variable information in a 'called script' is not available to the main script.

Example ... Main script (Main.ps1)

# This script checks to see if Exchange command are loaded and if not loads them into PowerShell
Invoke-Expression .\LoadExchange.ps1

(This seems to work just fine!)

I have another script that prompts for a Mailbox name (assumed SamAccountName/Alias) is entered

Invoke-Expression .\ValidateMailbox.ps1

Here is ValidateMailbox.ps1
Do
{
    $Error.clear()
    $Temp = Read-Host 'Please enter the user logon name' -ErrorAction SilentlyContinue
    $Mailbox = Get-Mailbox $Temp
    If ($Error[0])
        {
        $Logon = "error"
        }
    Else
        {
        $Logon = "good"
        }
}
While ($Logon -eq "error")

When I run these commands inside the 'main' script everything works fine. If I call the ValidateMailbox.ps1; I am prompted to enter data however the information stored in $Mailbox is not available ... I know this doesn't extend outside the scope of the script from which is run.  

I have found lots of examples of passing parameters TO a script but can't seem to find a solution where a called script passes $variables back to the 'Main' script.
0
Comment
Question by:winsystems
  • 2
  • 2
  • 2
6 Comments
 
LVL 71

Expert Comment

by:Qlemo
ID: 41872821
If you run a script dot-sourced, it will be executed in the same scope.
Example:
. .\ValidateMailbox.ps1
$mailbox

Open in new window

Note the "dot space" syntax.
0
 
LVL 41

Expert Comment

by:footech
ID: 41872860
More complex, but you can also specify the scope of specific variables.
Example syntax would be $global:mailbox = Get-Mailbox $Temp

I'd suggest reading the "about_scopes" PS help topic.
0
 

Author Comment

by:winsystems
ID: 41874127
I tried to get the "dot-sourced" to work but couldn't ... mainly because I was using the full path name including "C:"receiving the message of "The term '.c:\Scripts\validatemailbox.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program".  It is amazing how such a little thing can cause frustration for a beginner.

After doing some further reading about scopes; I have another question as they pertain to the "Scope-Modifier" in the examples below:
The syntax for a scope modifier in a variable is:
        $[<scope-modifier>]:<name> = <value>
The syntax for a scope modifier in a function is:
        function [<scope-modifier>]:<name> {<function-body>}

Reference: about_Scopes

The scope modifier seems to be specific name like “Global”, “Script” or “Private”, correct? Assuming I understand this correctly there can be more than one $global:<variable_name> used in one or more ‘child scripts’ with variable information available to the ‘Main.ps1’ script as long as the <variable_name> for each child script is unique, correct?  

I am thinking of re-writing my administrative scripts to be a series of scripts calling other scripts other than the several hundred lines that they currently are as many of the processes we run are similar such as validation and error checking and while dot sourced is simple; scopes might provide some programing advantage

Thanks to all for assistance
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

 
LVL 71

Accepted Solution

by:
Qlemo earned 1000 total points
ID: 41874375
The combination of scrope and variable name has to be unique for unique variables. $global:a is something different than $global:b. $script:a and $global:a are different.

More, since any change on a variable without scope implies it is the var in the nearest scope, but that does not apply to reading vars, you get the effect that you can see a global var value, but not change - changing is creating a local var. If you use the scope modifier, it is clear what you create and get.
Example (this are, of course, in fact two scripts):
$a = 1
c:\scripts\subscript.ps1
  # --- now in subscript.ps1:
  $a = $a +1
  write-host $a
  return
  # --- again in main script
write-host $a

Open in new window

will output 2, then 1.

Re dot-sourcing: There is a dot, then a space, then the scriptname (with path). You need to write
. c:\Scripts\validatemailbox.ps1
# or
. 'c:\Scripts\validatemailbox.ps1'

Open in new window

0
 
LVL 41

Assisted Solution

by:footech
footech earned 1000 total points
ID: 41874395
As Qlemo noted, don't forget the space after the initial dot.  It's required whether you use the full path or not.

Personally, I've only ever used the "global" and "script" scope modifiers (my needs have been pretty simple).  Yes you can have as many variables as you want specified with the modifier.  The names don't necessarily have to be unique, just be aware of when it's OK to update the contents of a variable.  It may be less error prone to make them all unique, but just like in a single script with only one scope it's OK to reuse a variable name if you don't need the old contents anymore.
0
 

Author Closing Comment

by:winsystems
ID: 41874697
Thanks all for the helpful information.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Stellar Exchange Toolkit: this 5 in 1 toolkit comes loaded with mega-software tool. Here’s an introduction to tools’ usage and advantages:
Measuring Server's processing rate with a simple powershell command. The differences in processing rate also was recorded in different use-cases, when a server in free and busy states.
In this video we show how to create an email address policy in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.:  First we need to log into the Exchange Admin Center. Navigate to the Mail Flow…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

885 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question