Powershell新手 - 获取所有httpd进程并循环遍历它们

时间:2015-08-10 18:14:03

标签: powershell

如何在power-shell中获取所有进程并循环遍历它们并在内存达到X阈值时重新启动它们? 例如,我知道这个命令

PS C:\Users\me> gwmi -ComputerName "localhost" -Class Win32_PerfFormattedData_PerfProc_Process -Filte
r "name like 'httpd%'"

这将给我所有httpd进程(httpd,httpd#1,...)。 我想循环遍历这些并检查是否已达到内存消耗阈值,如果是,请重新启动该过程。

我的问题主要是如何编写循环,而不是如何停止和重新启动服务。请解释一下,因为我之前从未编写过power-shell脚本。

更新: 我添加了更多信息以更好地解释我的问题。下面的代码有评论显示在哪里看到问题(问题1和问题2):

$ServiceExe="httpd#1"
$ServiceEXE2="httpd"

# Service to restart ('short' service name from Service's property)
$Service="httpd.exe"

# Working set threshold of 0.2 GB
$Threshold =  200000000

# Get service processes 'httpd' and 'httpd#1'
$Process = Get-WmiObject -ComputerName "localhost" -Class Win32_PerfFormattedData_PerfProc_Process -Filter "Name='$ServiceExe'"
$Process2 = Get-WmiObject -ComputerName "localhost" -Class Win32_PerfFormattedData_PerfProc_Process -Filter "Name='$ServiceExe2'"

# Get working set memory usage for both processes and convert to GB
$wsm = $Process.WorkingSet /1024/1024/1024;
$wsm2 = $Process2.WorkingSet /1024/1024/1024;
$thgb = $Threshold/1024/1024/1024

# Format to 3 dec places
$Fwsm = $("{0:0.000}" -f $wsm);
$Fthgb =$("{0:0.000}" -f $thgb);

echo $("WorkingSet : "+ $Fwsm + " GB / Threshold : " + $Fthgb  + " GB.") >> C:\temp\pslog.txt;

if($Process.workingset -gt $Threshold)
{
    #PROBLEM 1: THIS WILL ONLY EXECUTE ONCE PROCESS CAPS MAX MEMORY (2GB)
    stop-process -name $Service -force
    stop-Service apache2.2;
    start-Service apache2.2;
    echo "Restarted" >> C:\temp\pslog.txt;
}
else
{
    #PROBLEM 2: THIS WILL NEVER EXECUTE FOR SOME REASON
    $delta = $("{0:0.000}" -f ($thgb - $wsm));
    echo $("No Restarting as " + $delta + " GB remains.");
}

我正在考虑更换变量持有流程' httpd'和' httpd#1'我可以通过一个单独的集合,但意识到Apache可能有超过2' httpd'流程(即' httpd',' httpd#1',' httpd#2',' httpd#3',' httpd #4',...)。另外,我发现我在上面的更新代码中标记了2个问题。

知道我在上面的代码中做错了什么以及如何重写它以使用循环来遍历可能启动的所有 apache进程,而不仅仅像上面的示例中那样。 / p>

更新2: 所以,我重写了我的ps脚本,我的大部分工作都在运行,但我遇到了一个问题,希望最后一个问题。 在我的power-shell脚本中,我定义了具有我的服务名称的变量:

$ServiceName = "APACHESRV[DBx14]";

我的Windows->服务中存在APACHESRV [DBx14]服务。 然后在我的power-shell脚本中,我使用stop-service,start-service来启动服务:

  echo $("Stopping: " + $ServiceName) >> C:\temp\pslog.txt;
  stop-Service $ServiceName;
  echo $("Starting: " + $ServiceName) >> C:\temp\pslog.txt;
  start-Service $ServiceName;
  $stamp = Get-Date
  echo $($stamp + " Started: " + $ServiceName) >> C:\temp\pslog.txt;

这恰好回应了所有内容,power-shell没有显示任何错误(红线),但是我的服务没有启动。

非常感谢

3 个答案:

答案 0 :(得分:1)

应该这样做......

ps | where { $_.name -like "httpd*" } | foreach { 
    # interrogate the System.Diagnostics.Process object in $_ and do stuff with it
    $_
}

答案 1 :(得分:1)

使用 $('.article-link').on('click',function(e){ window.location = $( "article" ).find( ".url-text" ).text(); }); cmdlet获取所有httpd进程,并使用Get-Process cmdlet循环遍历它们:

ForEach-Object

答案 2 :(得分:1)

此时,我认为你只是错过了你的循环。您正在检索两个过程对象,但您只是在处理第一个过程对象。我冒昧地重组它来处理所有的http进程。试试这个:

# Working set threshold of 0.2 GB 
$Threshold = 200000000 
$thgb = $Threshold/1024/1024/1024 
$Fthgb =$("{0:0.000}" -f $thgb)

# Get service processes 'httpd' and 'httpd#1' Get-WmiObject -ComputerName "localhost" -Class Win32_PerfFormattedData_PerfProc_Process | where { $_.Name -like "httpd*" } | foreach {
    $procobj = $_

    # Get working set memory usage for both processes and convert to GB
    $wsm = $procobj.WorkingSet /1024/1024/1024;

    # Format to 3 dec places
    $Fwsm = $("{0:0.000}" -f $wsm)

    echo $("WorkingSet : "+ $Fwsm + " GB / Threshold : " + $Fthgb  + " GB.") >> C:\temp\pslog.txt;

    if($procobj.workingset -gt $Threshold)
    {
        stop-process -name $procobj.Name -force #check this, probably wrong name
        stop-Service apache2.2;
        start-Service apache2.2;
        echo "Restarted" >> C:\temp\pslog.txt;
    }
    else
    {
        $delta = $("{0:0.000}" -f ($thgb - $wsm));
        echo $("No Restarting as " + $delta + " GB remains.");
    } 
}