PowerShell寻找重复的流程

时间:2014-04-11 16:40:04

标签: powershell process wmi

此代码确实有效。但是,我无法确定它是否是Notepad.exe或TextPad.exe .. $ a.Name变量无法正常工作..

$log = "D:\WORK\ps\duplicate.txt"
If (test-path -path $log) {
Remove-Item $log
}

##$query = "Select * from win32_Process where name like '%script%'"
$query = "Select * from win32_Process where name like '%pad%'"

#$a = Get-WmiObject -Query $query | select name, processID | sort name

$SERVERS = get-content -Path D:\WORK\ps\monitored_computers.txt
$(Foreach ($server in $SERVERS) {
    $a = Get-WmiObject -Query $query -ComputerName $server | select name, processID | sort name
    IF ($a.Count -gt 1 ) { $server + " count: " + $a.Count + " name: " + $a.name | Out-File -append -filepath $log -encoding ASCII }
})

If (test-path -path $log) {
    send-mailmessage -from "sender@company.com" -to "receiver@company.com" -subject "Duplicated processes" -body "Please see attached"  -Attachment $log -dno onSuccess, onFailure -smtpServer smpthost.company.com
}

2 个答案:

答案 0 :(得分:2)

$a返回多于1个结果时,

Get-WmiObject是一个数组。虽然数组元素具有Name属性,但数组本身却没有。如果希望能够直接从数组变量访问元素属性,则需要PowerShell v3或更高版本。

PowerShell v2:

PS C:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
2      0      -1     -1

PS C:\> $qry = "SELECT * FROM Win32_Process WHERE Name LIKE '%pad%'"
PS C:\> $a = gwmi -Query $qry | select Name, ProcessId
PS C:\> $a.Name
PS C:\> $a | ft -Auto

Name        ProcessId
----        ---------
notepad.exe      1812
notepad.exe      1728

PowerShell v3:

PS C:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
3      0      -1     -1

PS C:\> $qry = "SELECT * FROM Win32_Process WHERE Name LIKE '%pad%'"
PS C:\> $a = gwmi -Query $qry | select Name, ProcessId
PS C:\> $a.Name
notepad.exe
notepad.exe
PS C:\> $a | ft -Auto

Name        ProcessId
----        ---------
notepad.exe      3460
notepad.exe      3580

在PowerShell v2或更早版本中,如果要访问其属性,则需要获取单个数组元素:

PS C:\> $a[0].Name
notepad.exe

或者您可以选择/展开该属性:

PS C:\> $a | select -Expand Name
notepad.exe
notepad.exe

但是,我不太清楚你想要的输出是什么。你想要所有* pad可执行文件的名称(例如Notepad.exe Notepad.exe Textpad.exe Notepad.exe)吗?只是唯一的名字(Notepad.exe Textpad.exe)?每种打击垫类型的数量(3 Notepad.exe, 1 Textpad.exe)?还有别的吗?

此外,$a并不保证是一个数组。根据{{​​1}}返回的内容,它也可以是单个对象(没有Get-WmiObject属性)或Count(无结果)。更好的改变

$null

if ( $a.Count -gt 1 ) { ... }

答案 1 :(得分:0)

@Ansgar Wiechers完美地解释了这一点。 您还可以使用Foreach-object来实现此目的。

IF ($a.Count -ge 1 ) { $a | foreach-object {" count: " + $a.Count + " name: " + $_.name| Out-File -append -filepath $log -encoding ASCII }}