1

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.

  • What is `Get-Data`? A script or function? It looks like a path to a script, in which case try using the full path, since the new process will not start in the current directory unless you give pass in the WorkingDirectory parameter to Start-Process. – Mike Zboray Jun 02 '15 at 19:34
  • 3
    Instead of cluttering your desktop with PowerShell windows I suggest you start looking into [jobs](http://stackoverflow.com/a/22585698/1630171). – Ansgar Wiechers Jun 02 '15 at 19:47
  • 1
    The problem with writing the full path is it needs to be in quotes because there are spaces in the path name. Also it is a script, but I kinda turned it into a function because it needs inputs. I'm looking into jobs now. – joe bredestege Jun 03 '15 at 11:18

1 Answers1

0

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

FSCKur
  • 920
  • 7
  • 16