0

I'm trying to call a new shell due to a memory leak from a library. When I call the shell, I need to pass an arg (the real code will pass 2 args). After the block of code has executed in the new shell, it needs to return a value. I wrote some test code to reproduce the error:

Function GetLastName
{
    Param ($firstName)

    $lastName = Powershell -firstName $firstName {
        Param ([string]$firstName)
        $lastName = ''
        if ($firstName = 'John')
        {
            $lastName = 'Doe'
            Write-Host "Hello $firstName, your last name is registered as $lastName"
        }
        Write-Host "Last name not found"
        Write-Output $lastName
    }
    Write-Output $lastName
}

Function Main
{
    $firstName = 'John'

    $lastName = GetLastName $firstName

    Write-Host "Your name is $firstName $lastName"
}

Main

The error I get...

Powershell : -firstName : The term '-firstName' is not recognized as the name of
a cmdlet, function, script file, or operable
At C:\Scripts\Tests\test1.ps1:5 char:15
+         $lastName = Powershell -firstName $firstName {
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (-firstName : Th...e, or operable :String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

program. Check the spelling of the name, or if a path was included, verify that
the path is correct and try again.
At line:1 char:1
+ -firstName John -encodedCommand DQAKAAkACQAJAFAAYQByAGEAbQAgACgAWwBzAHQAcgBpAG4A ...
+ ~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (-firstName:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Can anyone help me how to do this?

3
  • Use Start-Job approach. It also provide proper separation for Host stream. Commented Jan 24, 2016 at 18:11
  • Seems pretty complicated. Can you give an example in the answer section? Commented Jan 24, 2016 at 18:42
  • Please stop putting the language tag in the subject of your questions. Commented Jan 24, 2016 at 18:46

2 Answers 2

2

The syntax for calling powershell.exe to execute a scriptblock from within PowerShell is a bit different:

powershell.exe -command { scriptblock content here } -args "arguments","go","here"

So in your script that should be:

$lastName = powershell -Command {
    Param ([string]$firstName)
    $lastName = ''
    if ($firstName = 'John')
    {
        $lastName = 'Doe'
        Write-Host "Hello $firstName, your last name is registered as $lastName"
    } else {
        Write-Host "Last name not found"
    }
    Write-Output $lastName
} -args $firstName
Sign up to request clarification or add additional context in comments.

1 Comment

oh let me test this. Thanks for the reply.
1

Split your code into two separate scripts and use one just as a launcher for the second. Something like this:

# launcher.ps1
powershell.exe -File 'C:\path\to\worker.ps1' -FirstName $firstName

# worker.ps1
[CmdletBinding()]
Param($firstName)

$lastName = ''
if ($firstName = 'John') {
    $lastName = 'Doe'
    Write-Host "Hello $firstName, your last name is registered as $lastName"
}
Write-Host "Last name not found"
Write-Output $lastName

Note, however, that from the caller perspective the host output (Write-Host) of the new process is merged into its regular output (Write-Output).

1 Comment

well, I was hoping to keep the code in one file, but it looks like this is the best option. The Start-Job is adding unwanted attributes in the table I create.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.