'export a string from poweshell 1 to powershell 2

I have a shell script file.

./1.ps1
./2.ps1

I generate a string such as env-0 in 1.ps1 and need to export it to 2.ps1.
UPDATE:

1.ps1 generate many string and I couldn't pass my env-0 as argument to 2.ps1.

Do you have another solution?



Solution 1:[1]

PowerShell's stream-like I/O model is a little unusual, but any value not captured is basically output - so to output the string env-0 from 1.ps1, this is literally all you need:

"env-0"

Now that 1.ps1 outputs a string value, we need some way to feed it to 2.ps1.

You can either rely on unbound positional arguments, which will automatically be available in the target script/function via the $args variable:

# 2.ps1
$envString = $args[0]

# work with your `$envString` value here

To invoke:

$envString = ./1.ps1
./2.ps1 $envString
# or
./2.ps1 $(./1.ps1)

You can also accept pipeline input by consuming the $input automatic input enumerator variable:

# 2.ps1
$input |ForEach-Object {
    $envString = $_
    # work with your `$envString` value here
}

To invoke:

./1.ps1 |./2.ps1 

This might be useful if you intend to provide multiple inputs to 2.ps1 in succession:

# This will execute `./1.ps1` 100 times, but `./2.ps1` will only be executed once, and the output continuously fed to it as pipeline input
1..100 |ForEach-Object { ./1.ps1 } | ./2.ps1

Finally, if you want to write scripts for more advanced scenarios (multiple input parameters, input validation, argument completion etc.), you'll want to explicitly declare named parameter(s) with a param() block:

# ./2.ps1
param(
  [Parameter(Mandatory)]
  [string]$Environment
)

# work with $Environment here

To invoke:

./2.ps1 -Environment $(./1.ps1)

It's worth noting that you can use the [Parameter()] attribute to modify the binding behavior so you still get pipeline support:

# ./2.ps1
param(
  [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
  [string]$Environment
)

# work with $Environment here

Now that we've added both the Position and a ValueFromPipeline flags, we can pass the string via the pipeline, by name, or positionally all at once:

# These all work now
./2.ps1 -Environment $(./1.ps1)
./2.ps1 $(./1.ps1)
./1.ps1 |./2.ps1

The only caveat is that you can't pipe multiple input values anymore - for that, you'll need to move the script body into a special process block:

# ./2.ps1
param(
  [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
  [string]$Environment
)

process {
  # work with $Environment here
}

The process block will execute exactly once for each pipeline input, so now piping multiple values works again ()along with the previous 3 examples:

1..100 |ForEach-Object { ./1.ps1 } | ./2.ps1

So that's my solution:

# 1.ps1
"env-0"
# 2.ps1
# ./2.ps1
param(
  [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
  [string]$Environment
)

process {
  # work with $Environment here
}

For more information about advanced parameters and their binding semantics and how to utilise them, see the about_Functions_Advanced_Parameters help topic

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1