Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

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

Posted on 2016-11-03
6
56 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 69

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 40

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
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 
LVL 69

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 40

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

Is Your AD Toolbox Looking More Like a Toybox?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

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

The following article is intended as a guide to using PowerShell as a more versatile and reliable form of application detection in SCCM.
The Nano Server Image Builder helps you create a custom Nano Server image and bootable USB media with the aid of a graphical interface. Based on the inputs you provide, it generates images for deployment and creates reusable PowerShell scripts that …
In this video we show how to create a Resource Mailbox in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.: Navigate to the Recipients >> Resources tab.: "Recipients" is our default selection …
The video tutorial explains the basics of the Exchange server Database Availability groups. The components of this video include: 1. Automatic Failover 2. Failover Clustering 3. Active Manager

860 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