Solved

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

Posted on 2016-11-03
6
41 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 68

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 39

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
[Webinar] Disaster Recovery and Cloud Management

Learn from Unigma and CloudBerry industry veterans which providers are best for certain use cases and how to lower cloud costs, how to grow your Managed Services practice in IaaS clouds, and how to utilize public cloud for Disaster Recovery

 
LVL 68

Accepted Solution

by:
Qlemo earned 250 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 39

Assisted Solution

by:footech
footech earned 250 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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Following basic email etiquette rules will help you write a professional email and achieve a good, lasting impression with your contacts.
This script can help you clean up your user profile database by comparing profiles to Active Directory users in a particular OU, and removing the profiles that don't match.
In this video we show how to create a Distribution Group 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 Recipients >>…
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…

910 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now