如何使用PowerShell提取所有服务的“可执行路径”

67
Get-Service *sql* | sort DisplayName | out-file c:/servicelist.txt
我有一个一行 PowerShell 脚本,用于提取本地计算机上运行的所有服务列表,现在,除了显示“状态”、“名称”和“显示名称”之外,我还希望显示“可执行文件路径”

或者只需在命令提示符下键入“wmic service get PathName”。 - nawfal
这不应该是 wmic service 'My Service' get pathname 吗? - Max Cascone
8个回答

91

我认为你需要使用WMI:

Get-WmiObject win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, State, PathName

更新 如果您想对所选数据执行某些操作,可以使用计算属性,如此处所述。

例如,如果您只想获取Pathname中引号内的文本,可以拆分双引号并取数组项1:

Get-WmiObject win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, @{Name="Path"; Expression={$_.PathName.split('"')[1]}} | Format-List

Get-CimInstance也可以用来实现相同的功能,请参见此处了解CIM和WMI之间的区别。

Get-CimInstance win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, @{Name="Path"; Expression={$_.PathName.split('"')[1]}} | Format-List

1
谢谢,但是使用“PathName”时,我得到的不是完整路径,而是像下面这样的东西:C:\Program Files (x86)\Microsoft SQL S... E:\apps\MySQL\MySQL Server 5.0\bin\mys...在一定数量的字符后,路径被截断了,有没有办法获取完整路径? - Abilash A
2
看起来你的评论缺少了一些内容,我猜测你已经将其显示到屏幕上并且路径被截断了。尝试通过 Format-List 进行管道传输以查看完整路径。 - David Martin
谢谢,我已经尝试了Format-List,它运行得很好。我能截取.exe后面的路径吗?例如`"C:\Program Files (x86)\Microsoft SQL Server\MSSQL.3\MSSQL\Binn\sqlservr.exe" -sSQLEXPRESS`我不需要.exe后面的路径部分,我需要像这样的东西`"C:\Program Files (x86)\Microsoft SQL Server\MSSQL.3\MSSQL\Binn\sqlservr.exe"`去掉引号会更好 - Abilash A
1
我已经添加了一个使用计算属性的示例,这应该会对你有所帮助。 - David Martin
1
如果 $.PathName.Split 不够灵活,那么您确实可以使用正则表达式:$.PathName -replace,它支持正则表达式,请参见此处:http://blogs.technet.com/b/heyscriptingguy/archive/2011/03/21/use-powershell-to-replace-text-in-strings.aspx - David Martin
显示剩余2条评论

12

由于在PowerShell Core中弃用了Get-WmiObject,因此您可以使用

Get-CimInstance -ClassName win32_service | ?{$_.Name -match '^sql'} | Select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt

如果您不需要针对正则表达式进行检查,也可以使用 -Filter 参数:

相反。

Get-CimInstance -ClassName win32_service -Filter "Name like 'sql%'" | Select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt

1
注意:在使用 Get-CimInstance 命令时,你可以添加 -Filter 或 -Query 参数来代替将结果传递到另一个筛选器中。 - DouglasHeriot

7

一种关于WMI查询的变体,可能更快(我刚刚为SCCM客户端完成了此操作)

$SQLService=(get-wmiobject -Query 'Select * from win32_service where Name like "*SQL*"') | Select-object Name, DisplayName, State, Pathname

另一个技巧是,如果你想要路径名称而不带双引号(这样你就可以对它们采取行动),则需要捕获多个 SQL 结果。
$SQLService | Select-Object Name, DisplayName, State, @{Name='PathName';Expression=$_.Pathname.replace('"','')}

使用 -queryget-wmiobject(或 get-ciminstance) 中的最大优点是处理速度。旧的示例获取完整列表,然后进行筛选,而后者直接抓取一个非常直接的列表。
只是添加两分钱 :)
干杯! Sean The Energized Tech

1
使用-Filter而不是-Query的变体。我预计在内部它非常相似,但可能会少打一点字:-) Get-WmiObject win32_service -Filter 'Name like "%SQL%"' - Martin Hollingsworth
1
提供的答案对我不起作用。问题在于 where Name like "*SQL*" 应该是 where Name like "%SQL%"(请注意,% 是 SQL 的通配符)。 - Bozzy

2
你也可以使用正则表达式模式并将结果存储到文件中。
Get-WmiObject win32_service | ?{$_.Name -match '^sql'} | select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt

1

使用完整路径的 Format-List 变体,结果为文件:

Get-WmiObject win32_service | Format-Table -Wrap -AutoSize -Property State,Name,PathName | out-file C:\servicelist.txt

1
我对已接受答案使用Expression={$_.PathName.split('"')[1]}}感到不舒服,因为它不能处理我在数据中看到的引号、空格和参数变体。
这是一种笨拙的方法来处理。
function PathFromServicePathName($pathName) {
  # input can have quotes, spaces, and args like any of these:
  #   C:\WINDOWS\system32\lsass.exe
  #   "C:\Program Files\Realtek\Audio\HDA\RtkAudioService64.exe"
  #   C:\WINDOWS\system32\svchost.exe -k netsvcs -p
  #   "C:\Program Files\Websense\Websense Endpoint\wepsvc.exe" -k ss

  # if it starts with quote, return what's between first and second quotes
  if ($pathName.StartsWith("`"")) {
    $pathName = $pathName.Substring(1)
    $index = $pathName.IndexOf("`"")
    if ($index -gt -1) {
      return $pathName.Substring(0, $index)
    }
    else {
      # this should never happen... but whatever, return something
      return $pathName
    }
  }
  
  # else if it contains spaces, return what's before the first space
  if ($pathName.Contains(" ")) {
    $index = $pathName.IndexOf(" ")
    return $pathName.Substring(0, $index)
  }
  
  # else it's a simple path
  return $pathName
}

Get-WmiObject win32_service | select Name, DisplayName, @{Name="Path"; Expression={PathFromServicePathName $_.PathName}} | Format-List

0
在Powershell 7中添加了这个属性,因此您也可以同时使用Get-Service命令:
Get-Service *sql* | Select-Object -Property Status, Name, DisplayName, BinaryPathName

0
对于我来说,在PowerShell中
PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.17763.3770

添加选择路径有效并打印:
PS C:\> Get-Service -Name *sql* | Select Path

Path
----
"C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\Binn\sqlservr.exe" -sMSSQLSERVER

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接