Process or program running on specific machines using powershell

huangapple go评论53阅读模式
英文:

Process or program running on specific machines using powershell

问题

I'm new in the world of programming and on PowerShell scripting. My colleague gave me this command to run to identify if YES or NO the program PROGRAM.EXE is running on a list of computers. But I found it hard to do it on over 50 machines. I want to run it using PowerShell the ForEach function.

This is what I've done already but I don't have the expected result.
Usually, he uses this:

> tasklist /s COMPUTER1 /svc /fi "IMAGENAME eq PROGRAM.EXE"

This gives several results, and when the program is installed, it returns the name and the PID of the program. Otherwise, it says aucune tâche en service ne correspond aux critères spécifiés.

I want to use it but with PowerShell, with the list of computers.

This is what I've tried but I feel blocked:

$postes = @('COMPUTER1', 'COMPUTER2', 'COMPUTER3')

Foreach($element in $postes) 
{ 
    $( tasklist /s $($element) /svc /fi "IMAGENAME eq PROGRAM.EXE" )
}

I expect to switch case the result if or no the program is installed. But the result is not controllable that way. Can someone help please.

Thank you all.

英文:

i'm new in the world of programming and on powershell scripting. My collegue gave me this command to run to identify if YES or NO the program PROGRAM.EXE is running on a list of computers. But i found it hard to do it on over 50 machines. I want to run it using powershell the forEach function.
This is what i've done already but i don't have the expected result.
Usually he uses this
> tasklist /s COMPUTER1 /svc /fi "IMAGENAME eq PROGRAM.EXE")
This gave several result and when the program is installed, it return the name, and the PID of the program , else it says aucune tƒche en service ne correspond aux critŠres sp‚cifi‚s.
I want to use it but with powershell, with the list of computers.

This is what i've tried but i feelled bloked

$postes = @('COMPUTER1', 'COMPUTER2', 'COMPUTER3')

Foreach($element in $postes) 
{ 
    $( tasklist /s $($element) /svc /fi "IMAGENAME eq PROGRAM.EXE")
}

I expect to switch case the result if or no the program is installed. But the result is not controlable that way. Can someone help please.

Thank you all.

答案1

得分: 0

如果您有权限远程访问这些计算机,并且这些计算机上启用了WMI,您可以使用 Get-WmiObject 命令。

$computers = Get-Content -Path computers.txt # 文本文件,每行一个计算机
foreach($computer in $computers){
    $processes = Get-WmiObject -ComputerName $computer -Query "SELECT Name FROM Win32_Process WHERE Name = 'PROGRAM.EXE'"
    $programRunning = $processes.Count -gt 0
    [PSCustomObject]@{ Computer = $computer; ProgramRunning = $programRunning }
}

或者,如果您更喜欢一行命令:

cat computers.txt|%{[pscustomobject]@{Computer=$_;Running=[bool](gwmi -cn $_ -q "Select * FROM Win32_Process WHERE Name='PROGRAM.EXE'")}}

如果您需要快速运行它,我建议使用 PowerShell Gallery 上的 PSParallel 模块并行运行它。

这将允许您在一行命令中使用 Invoke-Parallel 命令:

Install-Module PSParallel -Scope CurrentUser
cat computers.txt|Invoke-Parallel{[pscustomobject]@{Computer=$_;Running=[bool](gwmi -cn $_ -q "Select * FROM Win32_Process WHERE Name='PROGRAM.EXE'")}}
英文:

If you have permissions to access these computers remotely, and WMI is enabled on those computers, you can use the Get-WmiObject cmdlet.

$computers = Get-Content -Path computers.txt # Text file with one computer on each line
foreach($computer in $computers){
    $processes = Get-WmiObject -ComputerName $computer -Query "SELECT Name FROM Win32_Process WHERE Name = 'PROGRAM.EXE'"
    $programRunning = $processes.Count -gt 0
    [PSCustomObject]@{ Computer = $computer; ProgramRunning = $programRunning }
}

Or if you prefer it in a one-liner:

cat computers.txt|%{[pscustomobject]@{Computer=$_;Running=[bool](gwmi -cn $_ -q "Select * FROM Win32_Process WHERE Name='PROGRAM.EXE'")}}

If you need to run it quickly, I would suggest running it in parallel using the PSParallel module from the PowerShell Gallery.

This would let you use the Invoke-Parallel cmdlet in the one-liner:

Install-Module PSParallel -Scope CurrentUser
cat computers.txt|Invoke-Parallel{[pscustomobject]@{Computer=$_;Running=[bool](gwmi -cn $_ -q "Select * FROM Win32_Process WHERE Name='PROGRAM.EXE'")}}

答案2

得分: 0

根据您想要查询的远程计算机数量,您可以检查是否可以在循环中访问每台计算机,然后仅查询在线计算机...类似于这样的代码:

$computerList = Get-Content -Path 'c:\files\mycomputer.txt'
$NomProgramme = 'XWin_MobaX'

$data = 
foreach ($computer in $computerList) {
    if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
        Invoke-Command -ComputerName $computer -HideComputerName -ScriptBlock {
            [PSCustomObject]@{
                Computer       = $ENV:COMPUTERNAME 
                Online         = $True
                ProgramRunning = if (Get-Process -Name $USING:NomProgramme -ErrorAction SilentlyContinue) { $True } else { $false }  
            }
        } |
            Select-Object -ExcludeProperty RunspaceId
    }
    else {
        [PSCustomObject]@{
            Computer       = $computer 
            Online         = $false
            ProgramRunning = 'n/a'  
        }
    }
} 
$data | Format-Table -AutoSize
$data | Export-Csv -Path c:\files\Services.csv -NoTypeInformation

如果您要检查的计算机数量非常多,您可以切换到 PowerShell 版本 7 并使用其内置的 Foreach-Object -Parallel 功能并行运行命令。您可以在这里了解更多信息:获取帮助 Foreach-Object

英文:

Depending on the amount of remote computers you want to query you could check if you can reach each individual computer in a loop and only query the online ones ... something like this:

$computerList = Get-Content -Path 'c:\files\mycomputer.txt'
$NomProgramme = 'XWin_MobaX'

$data = 
foreach ($computer in $computerList) {
    if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
        Invoke-Command -ComputerName $computer -HideComputerName -ScriptBlock {
            [PSCustomObject]@{
                Computer       = $ENV:COMPUTERNAME 
                Online         = $True
                ProgramRunning = if (Get-Process -Name $USING:NomProgramme -ErrorAction SilentlyContinue) { $True } else { $false }  
            }
        } |
            Select-Object -ExcludeProperty RunspaceId
    }
    else {
        [PSCustomObject]@{
            Computer       = $computer 
            Online         = $false
            ProgramRunning = 'n/a'  
        }
    }
} 
$data | Format-Table -AutoSize
$data | Export-Csv -Path c:\files\Services.csv -NoTypeInformation

If you have really a lot of computers to check you may switch to PowerShell version 7 and use its builtin ability to run commands in parallel with Foreach-Object -Parallel You can read more about here: Get-Help Foreach-Object

huangapple
  • 本文由 发表于 2023年6月8日 06:00:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76427371.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定