简体   繁体   中英

Run function with Start-process within script

I am trying to initialize a TON of powershell windows to help complete a scan very quickly. Each window needs different input and I have an array variable giving that input. The start-process function seems to work, but it gives me the unknown function error if I use " and gives me absolutely no response when I use '

foreach($search in $Partlist){
    start-process powershell.exe -argumentlist '-nologo -noprofile -executionpolicy bypass -command .\Get-Data -search $search -department $PNdept -accuracy $accuracy; pause'
    start-sleep -s 5
}

I do not understand why I get the unknown function error, but I believe I get no response because the variables are not global, I've declared the variables global and still no luck. Maybe I'm missing something. Thanks.

To add to Ansgar Wiechars' answer, there is the following differentiator:

  • Jobs will start new processes under the hood but give you a lot of framework for running multiple instances, queuing and getting data back. However, starting a new process for each job is expensive in Windows.
  • Starting a new Powershell window is going to be at least as slow as a job but with he extra overhead of the visual elements, and the difficulty of getting results back to the calling process
  • Runspaces are probably going to execute a lot faster because they run as threads within the same process, which are much cheaper to instantiate because they use the existing process block (this is a Windows structure, not a PS one).

A great article is here: https://learn-powershell.net/2012/05/13/using-background-runspaces-instead-of-psjobs-for-better-performance/ but be aware of going too far: https://newsqlblog.com/2012/05/22/concurrency-in-powershell-multi-threading-with-runspaces/

To answer your point about the Global space, this is not global to the desktop session of the computer you are sitting at. This is global to the powershell process you are working in. Example: you create an environment variable with the following:

[System.Environment]::SetEnvironmentVariable("MyVar", 22, "User")

You spawn a new powershell window and check it with this:

$env:MyVar

You delete it with this:

Remove-Item env:\myvar

You spawn another new powershell window and the environment variable still exists. Further experimentation will show you that a new global scope is spawned with each new process.

So! Why do you get "Unknown function"? Because you expect certain aspects of your environment to match the calling process, but it does not hold. In this case:

  • Your command is not in the path that the new process is spawned at
  • Your variable values are not assigned, because you're passing them in single-quotes and the new process doesn't have them in scope

Use runspaces, or refer to this: PowerShell Executing a function within a Script Block using Start-Process does weird things with double quotes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM