I'm using
Start-Process grunt -ArgumentList 'serve' -PassThru
and add it to an ArrayList. When I view said ArrayList it shows cmd process, not actual node.js process that was launched. If I try to Stop-Process it, quite obviously, kills cmd process, not the running grunt. I can locate running grunt with Get-Process node.
The problem is I need multiple grunts running at the same time and I want a way to distinguish between them somehow. Is there any way I can get actual node process into PowerShell upon initializing it?
This happens because grunt is launched via grunt.cmd which is run by CMD. This file launches grunt in node.
Here is an example of how to find notepad2.exe launched from a CMD similarly to your example:
# start a CMD which starts notepad2 and then waits on it
$process = Start-Process -PassThru 'cmd.exe' '/c "C:\Program Files\Notepad2\Notepad2.exe"'
# Wait for notepad2 to be launched
Start-Sleep -Seconds 2
# find the children of CMD, and kill the one which is notepad2
(Get-CimInstance win32_process -Filter "ParentProcessId='$($process.Id)' AND Name = 'Notepad2.exe'") | %{ Stop-Process -Id $_.ProcessId}
Translating this for grunt:
# start Grunt via grunt.cmd
$process = Start-Process grunt -ArgumentList 'serve' -PassThru
# Wait for node to be launched
Start-Sleep -Seconds 2
# find the children of CMD, and kill the one which is node
(Get-CimInstance win32_process -Filter "ParentProcessId='$($process.Id)' AND Name = 'node.exe'") | %{ Stop-Process -Id $_.ProcessId}
grunt isn't a Win32 executable, it's a javascript file that's run by node.exe. The easiest way to get the instance of node that's running grunt would be to start it yourself:
$ps = start-process -passthru node -argumentlist "$env:APPDATA\npm\node_modules\grunt\bin\grunt"
Related
I am running a Node.JS app that is executing some powershell commands to set the DNS services for my WiFi interface.
Unfortunately, the script fails without admin permissions, so I am trying to elevate the script within node.js
Start-Process -FilePath powershell.exe -ArgumentList {
Write-Host "Hello"
Set-DnsClientServerAddress -InterfaceIndex 10 -ServerAddresses ("127.0.0.1", "8.8.8.8")
sleep 5
} -verb RunAs
For some reason, this isn't applying the changes, despite the script outputting "hello" and waiting for 5 seconds. Does anyone know why that might be?
Hi after my vm gets created I run the Azure Custom Script Extension which runs a powershell script. So the script does some basic tasks like create a share create some files and creates a powershell script and stored it on the vm. the last step in the custom vm extension script I have it attempt to setup a task scheduler job to call a powershell script that was created above and the script should end fromt he extension.
The problem isthe extension gets stuck in a running state and never stops. I wrote a log to find out the progress of the script and it shows it went through the whole script fine but it gets stuck in running and the task scheduler script does not run the job.
When i log in the vm manually I ran the script manually and it works fine. So I am not sure what is causing it to hang and what user it is running as the vm extension that is.I tried to run a powershell background job instead of the scheduler and I got the same symptoms above.
The below code is the task scheduler I tried to run the vm custom extension that does not work when trying to set it up through the custom extension but runs fine manually setup from the vm.
$jobname = "MasterFileWatcher"
$script = "c:\test\MasterFileWatcher.ps1"
$repeat = (New-TimeSpan -Minutes 1)
$action = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument "$script; quit"
$duration = ([timeSpan]::maxvalue)
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).Date -
RepetitionInterval $repeat -RepetitionDuration $duration
$msg = "Enter the username and password that will run the task";
$credential = $Host.UI.PromptForCredential("Task username and
password",$msg,"$env:userdomain\$env:username",$env:userdomain)
$username = $credential.UserName
$password = $credential.GetNetworkCredential().Password
$username = "$env:userdomain\testuser"
$password = "testpass"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd
Register-ScheduledTask -TaskName $jobname -Action $action -Trigger $trigger -RunLevel Highest -User $username -Password $password -Settings $settings
I found out the issue.
I had to set the username as system so the task scheduler could run as Localsystem account
Register-ScheduledTask -TaskName $jobname -Action $action -Trigger $trigger -RunLevel Highest -User "System" -Settings $settings
Hey guys first time poster long time reader, I'm having a bit of trouble with my script at the moment and was hoping some would check it out and point out where I've gone wrong, it is as follows:
$Servers = gc "C:\ServerList.txt"
$SB = {
Start-Process {cmd (C:\psexec.exe \\$Server -u username -p password cmd /c "echo.| powershell C:\Autolog.ps1")
}
Foreach ($Server in $Servers)
{
Start-Job -ScriptBlock $SB
}
Essentially what I'm trying to get this script to do is for Every server in "Serverslist.txt" Start a PSEXEC which then initiates an Powershell script on said server
What i'm seeing is that the jobs start but my psexec isn't triggering on the servers and i know that line is good as i've completed isolation testing on that command and manually triggered it
Note: Directories and Credentials remove to maintain privacy
This is likely way more complicated than it needs to be. I would run a scriptblock against that list of computers instead like so:
$cred = New-Object System.Management.Automation.PSCredential ("domain\username",(ConvertTo-SecureString 'password' -asplaintext -force))
foreach ($server in $servers) {
Invoke-Command -ComputerName $comp -ScriptBlock {. C:\Autolog.ps1} -Credential $cred
}
Your job doesn't know what $Server means because jobs run in their own process, and so don't access the parent process' variables. You have to pass the argument. Try this:
Start-Job -ScriptBlock $SB -ArgumentList $Server
Appreciate the help ended up nutting it out and getting it to do what want, the script is as follows:
$Servers = gc "C:\ServerList.txt"
Foreach ($Server in $Servers)
{
[String]$cmd = "& cmd (C:\psexec.exe \\$Server -u Username -p Password cmd /c C:\Autolog.bat)"
[ScriptBlock]$SB = [ScriptBlock]::Create($cmd)
Start-Job -ScriptBlock $SB -ArgumentList $Server
echo "Started Script on $Server"
}
I had to move some of the command out to a .bat because I don't have time to troubleshoot the issue but i'm essentially the C:\Autolog.bat contains "powershell.exe C:\Autolog.ps1" from the first script post
I am starting a new process using:
$removeArguments = "-Command `"&{import-module .\deploy-utility.psm1; RemoveSolutions -solutionNames $solutionNames -url $url;}`""
start-process powershell -ArgumentList $removeArguments -Wait
This works fine when run locally but when run in remote session the statement is simply ignored.
I have also tried moving the command to a separate file but this makes no difference.
$removeArguments = "-File .\deploy-utility-functions.ps1", "remove", "$solutionNames", "$url"
$script = {start-process powershell -ArgumentList $removeArguments -Wait -NoNewWindow | Out-Host}
Invoke-Command -ScriptBlock $script
Remote call:
$script = [scriptblock]::create("& '.\$targetFile' '$arguments'")
$result = Invoke-Command -Session $s -ScriptBlock $script
Any suggestions?
You can have issues with permissions in remote sessions for the second hop ( Permissions of the started process in your case).
See enabling credssp http://ss64.com/ps/enable-wsmancredssp.html
I have a PowerShell script that is run automatically when our monitoring service detects that a website is down.
It is supposed to stop the AppPool (using Stop-WebAppPool -name $AppPool;), wait until it is really stopped and then restart it.
Sometimes it the process does not actually stop, manifested by the error
Cannot Start Application Pool:
The service cannot accept control messages at this time.
(Exception from HRESULT: 0x80070425)"
when you try to start it again.
If it takes longer than a certain number of seconds to stop (I will chose that amount of time after I have timed several stops to see how long it usually takes), I want to just kill the process.
I know that I can get the list of processes used by workers in the AppPool by doing dir IIS:\AppPools\MyAppPool\WorkerProcesses\,
Process ID State Handles Start Time
---------- ----- ------- ----------
7124 Running
but I can't figure out how to actually capture the process id so I can kill it.
In case that Process ID is really the id of process to kill, you can:
$id = dir IIS:\AppPools\MyAppPool\WorkerProcesses\ | Select-Object -expand processId
Stop-Process -id $id
or
dir IIS:\AppPools\MyAppPool\WorkerProcesses\ | % { Stop-Process -id $_.processId }
In Command Prompt on the server, I just do the following for a list of running AppPool PIDs so I can kill them with taskkill or Task Mgr:
cd c:\windows\system32\inetsrv
appcmd list wp
taskkill /f /pid *PIDhere*
(Adding answer from Roman's comment, since there maybe cache issues with stej's solution)
Open Powershell as an Administrator on the web server, then run:
gwmi -NS 'root\WebAdministration' -class 'WorkerProcess' | select AppPoolName,ProcessId
You should see something like:
AppPoolName ProcessId
----------- ---------
AppPool_1 8020
AppPool_2 8568
You can then use Task Manager to kill it or in Powershell use:
Stop-Process -Id xxxx
If you get Get-WmiObject : Could not get objects from namespace root/WebAdministration. Invalid namespace then you need to enable the IIS Management Scripts and Tools feature using:
ipmo ServerManager
Add-WindowsFeature Web-Scripting-Tools