PowerShell: Starting process with variable parsed from Get-Process - powershell

I am currently writing a PowerShell script to stop a few processes, start a program, and then restart those processes. The problem arises when I feed the processes into an array variable to restart them later.
My code:
$direc = "C:\Program Files (x86)\PathTo\Program.exe";
$arguments = "/theseArguments1", "/theseArguments2";
$processesDefined = #();
$processes = "notepad", "explorer";
ForEach ($i in $processes)
{
$processesDefined += get-process -name $i | select-object path;
get-process -name $i | stop-process -force;
}
start-process -filepath $direc -ArgumentList $arguments -NoNewWindow -wait;
ForEach ($i in $processesDefined)
{
start-process -filepath $i;
}
When debugging the $processesDefined.Count displays 2 and the $processesDefined displays as expected yet when it gets to tjhe time to start the processes I get:
Start-Process : This command cannot be executed due to the error: The system ca
nnot find the file specified.
At D:\Desktop\Aion.ps1:17 char:18
+ start-process <<<< -FilePath $i;
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOp
erationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.C
ommands.StartProcessCommand
I've done a lot of searching but can't find anything of real help. Any help with this would be greatly appreciated. Thank you.
Output of $processesDefined:
[DBG]: PS D:\Desktop>>> $processesDefined
Path
----
C:\Program Files\Windows Media Player\wmpnetwk.exe
C:\Windows\explorer.exe
_____________________________________________________________

Try doing it this way. The way you are doing it leaves the variable $processesDefined with a table heading (PATH) and this will screw things up.
$processesDefined += (get-process -name $i).Path
This way will just give you the path with no table heading

Related

tshark job on PowerShell does not output capture file

When I run the following command in my script I expect packet_dump.pcap to get generated after I stop the script but nothing gets generated.
Start-Job -Name $tsharkJobName -ScriptBlock { & $tsharkPath --interface $interfaceNo -w "packet_dump.pcap" } | Out-Null
When I run the line below:
Receive-Job $tsharkJobName -Force
This is the error message that I get (where $interfaceNo is 5 which is the ID for Wi-Fi):
Capturing on 'Wi-Fi'
+ CategoryInfo : NotSpecified: (Capturing on 'Wi-Fi':String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : localhost
I have this at the end of the script as well:
finally {
Stop-Job $tsharkJobName
Remove-Job $tsharkJobName -Force
}
$args = "--interface " + $interfaceNo + " -w packet_dump.pcap"
Start-Process $tsharkPath -ArgumentList $args -NoNewWindow
and
finally {
Stop-Process -Name "tshark"
}
Solves this.

How run a command in PowerShell from a specified directory and wait for it to complete before moving on?

I have a script that works to run an executable and wait until done in PS but I need to modify it to use a path defined in a variable earlier in the script.
Working:
$job = Start-Job `
-InitializationScript { Set-Location C:\MyDirectory\ } `
-ScriptBlock { C:\MyDirectory\MyCmdLineExecutable.exe }
Wait-Job $job
Receive-Job $job
Not working:
$Path = "C:\MyDirectory\"
$ExePath = $path+"MyCmdLineExecutable.exe"
$job = Start-Job `
-InitializationScript { Set-Location $Path } `
-ScriptBlock { $ExePath }
Wait-Job $job
Receive-Job $job
Here's the error:
Set-Location : Cannot process argument because the value of argument "path" is null. Change the value of argument "path" to a non-null value.
At line:1 char:2
+ Set-Location $Path
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Location], PSArgumentNullException
+ FullyQualifiedErrorId : ArgumentNull,Microsoft.PowerShell.Commands.SetLocationCommand
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
49 Job49 BackgroundJob Failed False localhost $ExePath
Running startup script threw an error: Cannot process argument because the value of argument "path" is null. Change the value of argument "path" to a non-null value..
+ CategoryInfo : OpenError: (localhost:String) [], RemoteException
+ FullyQualifiedErrorId : PSSessionStateBroken
Combining info from Start-Job docs with About_Scopes article, I am certain of that you need to use -InputObject parameter:
Specifies input to the command. Enter a variable that contains the
objects, or type a command or expression that generates the
objects. In the value of the ScriptBlock parameter, use the
$Input automatic variable to represent the input objects.
$Path = "C:\MyDirectory\"
$ExePath = $path+"MyCmdLineExecutable.exe"
$job = Start-Job -InputObject #( $Path, $ExePath) `
-InitializationScript { <# $Input variable isn't defined here #> } `
-ScriptBlock {
$aux = $Input.GetEnumerator()
Set-Location $aux[0]
& $aux[1] }
Wait-Job $job
Receive-Job $job
BTW, to run commands that are stored in variables and represented by strings, use & Call operator. See the difference:
$ExePath ### output only
& $ExePath ### invocation
I think you want Start-Process with the -Wait parameter. You can also specify the -WorkingDirectory parameter to specify the working directory for the new process. Example:
Start-Process notepad -WorkingDirectory "C:\Program Files" -Wait
Write-Host "Finished"
When you run this script, Notepad will open but the script won't continue until it closes. When you close Notepad, the Write-Host line runs.

Powershell: Capture process id of a background job

I want to start a background job and capture it's process id into a .pid file. I was able to do it with the Start-Process as follows:
Start-Process C:\process.bat -passthru | foreach { $_.Id } > start.pid
Now, I want to wrap Start-Process with Start-Job, to run it in the background, like this:
$command = "Start-Process C:\process.bat -passthru | foreach { $_.Id }"
$scriptblock = [Scriptblock]::Create($command)
Start-Job -ScriptBlock $scriptblock
Unfortunatelly, this doesn't work and Receive-Job gives me the following error:
The term '.Id' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (.Id:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName : localhost
Looks like it's something wrong with the $_ variable. Maybe it gets overwritten by the Start-Job.
Any clues greatly welcome!
That is because the variable is being expanded when using double quotes. If you want to keep the $_, then you need to use single quotes.
$command = 'Start-Process C:\process.bat -passthru | foreach { $_.Id }'
$scriptblock = [Scriptblock]::Create($command)
Start-Job -ScriptBlock $scriptblock

How to make powershell wait for exe to install?

So i've read every single answer related to this question but none of them seem to be working.
I've got these lines going on in the script:
$exe = ".\wls1033_oepe111150_win32.exe"
$AllArgs = #('-mode=silent', '-silent_xml=silent_install.xml', '-log=wls_install.log"')
$check = Start-Process $exe $AllArgs -Wait -Verb runAs
$check.WaitForExit()
After this runs I have a regex check on the installed files that replaces some specific strings, but no matter what I try to do it continues to run the regex check while the program is installing.
How can I make it so that the next line doesn't execute until it finishes installing the exe? I've also tried piping to Out-Null with no luck.
I created a test executable that did the following
Console.WriteLine("In Exe start" + System.DateTime.Now);
System.Threading.Thread.Sleep(5000);
Console.WriteLine("In Exe end" + System.DateTime.Now);
Then wrote this powershell script which as expected waits for the exe to finish running before outputting the text "end of ps1" and the time
push-location "C:\SRC\PowerShell-Wait-For-Exe\bin\Debug";
$exe = "PowerShell-Wait-For-Exe.exe"
$proc = (Start-Process $exe -PassThru)
$proc | Wait-Process
Write-Host "end of ps1" + (Get-Date).DateTime
This following powershell also correctly waits for the exe to finish.
$check = Start-Process $exe $AllArgs -Wait -Verb runas
Write-Host "end of ps1" + (Get-Date).DateTime
Adding the WaitForExit call gives me this error.
You cannot call a method on a null-valued expression.
At line:2 char:1
+ $check.WaitForExit()
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
However this does work
$p = New-Object System.Diagnostics.Process
$pinfo = New-Object System.Diagnostics.ProcessStartInfo("C:\PowerShell-Wait-For-Exe\bin\Debug\PowerShell-Wait-For-Exe.exe","");
$p.StartInfo = $pinfo;
$p.Start();
$p.WaitForExit();
Write-Host "end of ps1" + (Get-Date).DateTime
I think maybe you are confusing the Start-Process powershell command with the .NET framework Process object

Removing multiple apps using powershell?

I want to create a script to remove a bunch of apps. I want to do this without user interaction once I've started the script.
This is the script I have so far; it doesn't work but hopefully you can see what I'm trying to do:
$App = Get-Content "C:\ListOFApps.txt" #get a list of apps
$args= '/quiet /norestart' # stores arguments for start-process
#gwmi gets the list of applications
# where selects just the apps im interested in removing
# start-process removes each app using msiexec with quiet and norestart options
gwmi win32_product | where { $App -contains $_.Name } | foreach {Start-Process 'msicexec /uninstall ' $_.IdentifyingNumber -ArgumentList $args -wait}'
This is the error that occurred:
ForEach-Object : Cannot process command because of one or more missing mandatory parameters: Process.
At C:\Users\username\AppData\Local\Temp\406f96a1-19b4-4e0d-af1b-b1ac2e32a6ba.ps1:3 char:62
+ gwmi win32_product| where { $App -contains $_.Name }| foreach <<<<
+ CategoryInfo : InvalidArgument: (:) [ForEach-Object], ParameterBindingException
+ FullyQualifiedErrorId : MissingMandatoryParameter,Microsoft.PowerShell.Commands.ForEachObjectCommand
$_.IdentifyingNumber
Start-Process 'msicexec /uninstall $_.IdentifyingNumber' -ArgumentList $args -wait
You have an unbalanced single quote on the end of the line with the "foreach." I suspect fixing that is only the start of your problems. Good luck.
Also you have the Process misspelled. Should be "msiexec" not "msicexec"