日期:2014-05-17  浏览次数:20923 次

Windows PowerShell 2.0之进程管理

Windows PowerShell 2.0之进程管理
2010年12月18日
  进程在操作系统中用于处理数据和进程间的交换,PowerShell的进程和服务管理机制能分析进程信息,并且直接操作进程实例指向的对象。这样对象化的命令为用户在提取数据及修改状态方面提供了方便,管道命令的优点结合对象化的进程和服务可以简化复杂的命令。本文将讲解如何操作进程及其属性,包括启动和终止进程,以及查询并显示进程信息。
  在PowerShell中所有与进程相关的操作均由5个cmdlet来实现,即Get-Process、Start-Process、Stop-Process、Debug-Process和Wait-Process。下例获取所有与Process相关的cmdlet的方法:
  PS C:\> Get-Command -Noun Process
  CommandType Name Definition
  ----------- ---- ----------
  Cmdlet Debug-Process Debug-Process [-Name] 
  Cmdlet Get-Process Get-Process [[-Name] 
  Cmdlet Start-Process Start-Process [-FilePath] 
  Cmdlet Stop-Process Stop-Process [-Id] ...
  Cmdlet Wait-Process Wait-Process [-Name] 
  1 获取进程列表
  任务管理器是个强大的工具,但其仅提供了进程清单。PowerShell允许用户快速生成各种关于系统的报告,并可为管道传递所有信息。下例按照特定属性值排序所有进程并返回顶端的5个:
  PS C:\> Get-Process | sort VM -Descending | select -First 5
  Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
  ------- ------ ----- ----- ----- ------ -- -----------
  1621 39 74556 12908 894 645.19 3360 JAVAW
  383 19 40448 50784 559 195.64 2684 WINWORD
  835 34 68928 92044 433 57.38 6912 explorer
  1292 38 140732 7976 379 ...23.52 4620 msnmsgr
  542 18 33008 1600 243 320.83 5080 mysql
  其中有些程序占用了大量内存,但是并不是占用大量内存的程序就一定是导致系统变慢的直接原因。还需要分析更详细的数据才能得出结论,如下按照WS(Working Set)属性检查工作区:
  PS C:\> Get-Process | sort WS -Descending | select -First 5
  Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
  ------- ------ ----- ----- ----- ------ -- -----------
  846 34 68940 92060 434 57.66 6912 explorer
  384 19 40568 51488 561 212.33 2684 WINWORD
  221 10 65320 44572 183 263.77 4612 AcroRd32
  705 22 23340 23932 141 2,824.16 1236 mysql
  1621 39 74472 20256 894 647.58 3360 JAVAW
  如果怀疑由于颠簸(thrashing)使得机器速度变慢,则需要分别使用PM和NPM属性查看分页和未分页内存数。
  -【提示】---------
  颠簸是不执行任何处理的计算机活动,通常是因为内存或其他资源耗尽或有限而无法完成所要执行的操作。当这种情况发生时,程序通过操作系统发出请求。操作系统则试图释放其他程序中占用的资源,从而导致不能响应新的请求。在虚拟存储系统(使用页管理逻辑存储或内存的操作系统)中,颠簸即发生过度页请求操作的情况。
  发生颠簸的系统被认为是一个运行非常慢或一个进入暂停状态的系统。
  ------------------
  这样可以获取所有占用超过50MB物理内存的进程,这种类型的操作在PowerShell中频繁出现,所以PowerShell支持KB、MB和GB此类的数字单位后缀。下例为执行的操作:
  PS C:\> Get-Process | where {$_.WS -ge 50MB}
  Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
  ------- ------ ----- ----- ----- ------ -- -----------
  839 34 68096 191316 434 60.00 6912 JAVAW
  3062 32 61180 70812 237 88.36 7800 Mysql
  396 20 39556 56200 569 303.36 2684 WINWORD
  可以看到,当前系统由于Oracle数据库(Oracle使用Java虚拟机实现跨平台操作,这里的javaw即其进程)占用了大量的分页内存,所以导致系统运行速度变慢。
  2 启动和停止进程
  PowerShell中所有与进程相关的操作均通过调用.NET的System.Diagnostics.Process对象来实现,启动进程只需要键入可执行程序的文件名。为获取进程对象的实例句柄,以便后面对其进行操作,执行Get-Process命令:
  PS C:\> notepad
  PS C:\> Get-Process notepad
  Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
  ------- ------ ----- ----- ----- ------ -- -----------
  48 3 1668 4020 32 0.14 2400 notepad
  如果已经启动了多个notepad实例,则获取对应的实例可以通过进程ID或StartTime属性,但是这并不是最安全的一种途径。如在启动Notepad之后,运行Get-Process cmdlet之前,计算机的其他用户启动了Notepad实例,则使用这种方法获取的刚刚启动的进程并不是所需。获取刚刚启动进程句柄的最安全方法是在启动时使用Process.Start()静态方法,它会返回最新启动的进程句柄,如:
  PS C:\> $notepad = [Diagnostics.Process]::Start("notepad.exe")
  PS C:\> $notepad
  Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
  ------- ------ ----- ----- ----- ------ -- -----------
  44 3 1632 4000 32 0.19 2564 notepad
  如果不考虑操作过程中会丢失数据,则终止进程可以使用进程的Kill方法$notepad.Kill()或者传递进程实例给Stop-Process cmdlet杀死进程,如Get-Process notepad | Stop-Process。在不丢失数据的情况下,需要尝试调用CloseMainWindow方法通知进程在退出之前提示保存。如果已经保存,则直接终止该进程。下例尝试关闭Notepad窗口,等待5秒。如果没有保存,则退出时会提示保存;否则直接终止:
  PS C:\> notepad
  PS C:\> function KillNotepad()
  >> {
  >> $notepad = Get-Process notepad
  >> echo "T