Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > PowerShell

Vista Tutorial - Include another script, keep variables in included script?

Reply
 
Old 08-15-2008   #1 (permalink)
pschmidt
Guest


 
 

Include another script, keep variables in included script?


I want to run or include a PS script from within another PS script. But
want the values set in the 2nd one to be available in the first one.

For example:
tmp.ps1----
$Test = "Here"
$There = "There"

echo "TEST: $test"
echo "There: $there"
------------------------

Now tmp2.ps1-------------
echo "TEST: " $Test

..\tmp.ps1

echo "TEST: " $Test
echo "There: " $there
-------------

When I run tmp2.ps1, I get:
Quote:

> .\tmp2.ps1
TEST:
TEST: Here
There: There
TEST:
There:
--------------------------

I'd like the values set in 'tmp' to be available in tmp2. How do I do this?

Thx,



My System SpecsSystem Spec
Old 08-15-2008   #2 (permalink)
Kryten
Guest


 
 

Re: Include another script, keep variables in included script?

This is just one possible way:-
(Both scripts are in my 'D:\Posh' directory.

tmp.ps1
-----------
$Test = "Here"
$There = "There"
---------------------

tmp2.ps1
------------
&D:\Posh\tmp.ps1
" These variables and values are from tmp:"
Write-Host "$Test & $There"
----------------------------

Nowwith your current directory set as D:\Posh do
Quote:

>.\tmp2.ps1
You should get:-
These variables and values are from tmp:
Here & There

Essentially just using the 'Call' Operator '&' to include the tmp.ps1

Hope this helps,
Stuart


My System SpecsSystem Spec
Old 08-15-2008   #3 (permalink)
Kiron
Guest


 
 

Re: Include another script, keep variables in included script?

You can export the variables to tmp2's scope:

-< tmp.ps1 >-
param ([string[]]$exportVariable)

$Test = "Here"
$There = "There"

echo "TEST: $test"
echo "There: $there"

if ($exportVariable) {
foreach ($var in $exportVariable) {
set-variable $var (get-variable $var).value -scope 1
}
}
-< tmp.ps1 >-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
-< tmp2.ps1 >-
# $test echo "TEST: $Test"

# assuming both scripts are in same Dir
$cmd = join-path (split-path $myInvocation.myCommand.path) tmp.ps1
& $cmd -ex test, there

echo "TEST: $Test"
echo "There: $there"
-< tmp2.ps1 >-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
.\tmp2

--
Kiron
My System SpecsSystem Spec
Old 08-15-2008   #4 (permalink)
tojo2000
Guest


 
 

Re: Include another script, keep variables in included script?

On Aug 15, 8:18*pm, "Kiron" <Ki...@xxxxxx> wrote:
Quote:

> You can export the variables to tmp2's scope:
>
> -< tmp.ps1 >-
> param ([string[]]$exportVariable)
>
> $Test = "Here"
> $There = "There"
>
> echo "TEST: $test"
> echo "There: $there"
>
> if ($exportVariable) {
> *foreach ($var in $exportVariable) {
> * set-variable $var (get-variable $var).value -scope 1
> *}}
>
> -< tmp.ps1 >-
> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
> -< tmp2.ps1 >-
> # $test echo "TEST: $Test"
>
> # assuming both scripts are in same Dir
> $cmd = join-path (split-path $myInvocation.myCommand.path) tmp.ps1
> & $cmd -ex test, there
>
> echo "TEST: $Test"
> echo "There: $there"
> -< tmp2.ps1 >-
> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
> .\tmp2
>
> --
> Kiron
You might want to explain a solution like that, since variable
scoping, especially with the way PowerShell lets you do it, is a
difficult concept to get used to if you haven't dealt with it before.

When you assign a variable in PowerShell, by default the variable is
created in the current scope. If you are in a script block, then at
the end of the script block that variable will go "out of scope" and
be removed. Any script blocks or function calls after a variable is
declared, though, get access to the variable defined above.

The -scope option of Set-Variable allows you to set the scope of the
variable to a specific number of levels above the current scope. If
it is in a function, then it will set itself in the script's scope
that called it, and if it's in the script's highest scope then it will
be declared in the global scope.

The caveat with this method is that if you want to maintain that kind
of granularity then you have to know how many levels above the calling
statement you want the variable to be set to ahead of time. In
general it is a good idea to avoid declaring global variables as much
as possible because you increase your chances of having the same
variable name used twice, but this is not always practical.

BTW, if you do set the same variable twice then the innermost variable
will take precedence while it is in scope, and then you will revert to
the outer-scoped variable, since Powershell always starts with the
current scope and then works its way up when looking up a variable
name.
My System SpecsSystem Spec
Old 08-16-2008   #5 (permalink)
tojo2000
Guest


 
 

Re: Include another script, keep variables in included script?

On Aug 15, 9:36*pm, "Kiron" <Ki...@xxxxxx> wrote:
Quote:

> Hi tojo,
> In tmp.ps1 -- when the param -ExportVariable is not null -- Set-Variable sets variables in the Parent (1) scope, i.e. tmp2.ps1's scope when tmp.ps1 is called from tmp2.ps1, because the If statement does not create a child scope, so Set-Variable is not resetting the Local (0) scope variables. If instead of setting the new/exported variable in an 'Then' block you use a function/scriptblock to set it, the scope of the exported variable's scope would have to be the Grandparent's (2) because a Function/scriptblock does create a new scope.
>
> function ev ([string[]]$vns) {
> *foreach ($vn in $vns) {
> * sv $vn ((gv $vn -s 1).value * 3) -s 2
> *}
>
> }
>
> & {
> *& {
> * $v1 = 1
> * *if ($v1 -eq 1) {sv v1 2 -s 1}
> * *write-host `$v1 is $v1 in the Local scope
> * }
> *write-host `$v1 is $v1 in the Parent scope
>
> }
>
> # no $v1 in the Global scope
> $v1
>
> & {
> *& {
> * $v1 = 1
> * *if ($v1 -eq 1) {ev v1}
> * *write-host `$v1 is $v1 in the Local scope
> * }
> *write-host `$v1 is $v1 in the Parent scope
>
> }
>
> # no $v1 in the Global scope
> $v1
>
> Jeffrey Snover explains it here:http://blogs.msdn.com/powershell/arc...trolling-the-s...
>
> --
> Kiron
Sweet. Thanks. The control over scope is unprecedented in PowerShell
as far as I can tell, but the potential for confusion is unprecedented
as well.
My System SpecsSystem Spec
Old 08-16-2008   #6 (permalink)
Joel (Jaykul) Bennett
Guest


 
 

Re: Include another script, keep variables in included script?

On Aug 16, 4:54*am, tojo2000 <tojo2...@xxxxxx> wrote:
Quote:

> Sweet. *Thanks. *The control over scope is unprecedented in PowerShell
> as far as I can tell, but the potential for confusion is unprecedented
> as well.
The problem is, the solution being offered is waaay more complicated
than what you need. It's like the game of mousetrap.
All you had to do was dot-source the second script from the first,
which makes the second script execute in the first script's scope, so
any variables it defines are left behind when it's done.

For example:
## tmp1.ps1 ############
$Test = "Here"
$There = "There"

echo "TEST: $test"
echo "There: $there"
###########################

## tmp2.ps1 ############
echo "TEST: " $Test

# a dot, a space, then the path to the second script
. .\tmp1.ps1

echo "TEST: " $Test
echo "There: " $there
###########################

That's all. no need to mess with $global, or explicit scoping or any
of that.
My System SpecsSystem Spec
Old 08-17-2008   #7 (permalink)
Kiron
Guest


 
 

Re: Include another script, keep variables in included script?

Just because the code police may find the idea of importing specific variables --instead of importing every variable and define every function-- from the called script 'waaay more complicated', doesn't mean it isn't useful, and as long as someone 'gets' the concept and applies the technique, the purpose of sharing and demonstrating the power of PowerShell has been achieved.

--
Kiron
My System SpecsSystem Spec
Old 08-17-2008   #8 (permalink)
Kryten
Guest


 
 

Re: Include another script, keep variables in included script?

Hi Kiron,

Actually that was going to be my next question. If I understood
properly your method just extracts the variables from the target
script.
If so thats an awesome technique. I didn't know you could do that! But
then I am still at the "I don't even know what I don't know" stage.

I'm going to have to play around with that a bit because I have a
script that generates hostnames to IP addresses and sends output to a
text file but it would be great to call that script and just yank out
the variables without that script "following through" so to speak.
That way other ppl could use it without mucking up my personal outfile
files.

Appreciated!

Stuart


My System SpecsSystem Spec
Old 08-17-2008   #9 (permalink)
tojo2000
Guest


 
 

Re: Include another script, keep variables in included script?

On Aug 17, 12:36*am, "Kiron" <Ki...@xxxxxx> wrote:
Quote:

> Just because the code police may find the idea of importing specific variables --instead of importing every variable and define every function-- from the called script 'waaay more complicated', doesn't mean it isn't useful,and as long as someone 'gets' the concept and applies the technique, the purpose of sharing and demonstrating the power of PowerShell has been achieved.
>
> --
> Kiron
I disagree, and I'm no authority, so take it with whatever grain of
salt you need. The original question was how to call a script from
within a script and still use the variables created by that script
once it's done running. Your solution jumped to the most complicated
solution possible to the question and made several assumptions about
the problem being solved without even explaining what you were doing.
It's not that the idea of exporting a single variable is complicated
or has no value, it's that you just showed an example of a technique
that comes with a lot of caveats as a solution to a problem with a
simple solution.

My System SpecsSystem Spec
Old 08-17-2008   #10 (permalink)
Kiron
Guest


 
 

Re: Include another script, keep variables in included script?

Hi Kryten,
Suppose you have your IPs in 'c:\ips.txt' and the sample scripts are all in 'c:\'. 'scriptA.ps1' resolves the hostname for each IP and outputs it to a text file in a two-column format. 'scriptA.ps1' also lets you import variables from it to the caller's scope by using the -ExportVariable switch and by passing the variable name(s) to its -VariableName parameter. Note that both parameters are declared last in the Param declaration and the output file is not generated when exporting variables, this last is optional, you can remove the exit statement and 'scriptA.ps1' will generate the output file. 'scriptB.ps1' calls 'scriptA.ps1' and 'imports' variable $col.

-< scriptA.ps1 >-
param(
[string[]]$ips,
[string]$outFile,
[switch]$exportVariable,
[string[]]$variableName
)

$col = $(
foreach ($ip in $ips) {
trap [formatException] {
sv hostName 'Invalid IP' -s 1
continue
}
trap [net.sockets.socketException] {
sv hostName 'No data found' -s 1
continue
}
$hostName = [net.dns]::getHostByAddress($ip).hostName
$obj = new-object psObject
$obj | add-member noteProperty IP $ip -p |
add-member noteProperty HostName $hostName -p
}
)

if ($exportVariable -and $variableName) {
foreach ($var in $variableName) {
set-variable $var (gv $var).value -scope 1
}
# optional: exit the script, no output file generated
exit
}

$col | ft -a | out-string -s | ? {$_} > $outFile
-< scriptA.ps1 >-

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

-< scriptB.ps1 >-
# calls scriptA using the -ExportCollection switch and specifies the
# variables you want to export
c:\scriptA (gc c:\ips.txt) -export -var col
# $col is available
$col | ft HostName
-< scriptB.ps1 >-

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

-< scriptC.ps1 >-
# calls scriptA w/o importing variables
c:\scriptA (gc c:\ips.txt) c:\out.txt
-< scriptC.ps1 >-

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

Try this:

@'
128.183.240.121
--
207.46.19.254
72.246.25.89
55.55.55.55
69.17.117.207
208.80.152.2
'@ > c:\ips.txt

gc c:\ips.txt
c:\scriptB
c:\scriptC
gc c:\out.txt

--
Kiron
My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
Retaining variables after script execution PowerShell
Need help with PHP Script variables Network & Sharing
Pop-up to enter variables to pass to script PowerShell
Passing variables to script PowerShell
Best Approach for Included Script Files PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46