Powershell:如何找出哪些正在运行的服务不是';操作系统和非MS的t部分
有没有办法使用Powershell找出哪些运行的服务不是Windows的本机服务?换句话说,这些服务不是Windows操作系统的一部分,也是非Microsoft的。我想了解我们的供应商安装的所有服务。Powershell:如何找出哪些正在运行的服务不是';操作系统和非MS的t部分,powershell,service,Powershell,Service,有没有办法使用Powershell找出哪些运行的服务不是Windows的本机服务?换句话说,这些服务不是Windows操作系统的一部分,也是非Microsoft的。我想了解我们的供应商安装的所有服务。 查找正在运行的服务很容易: Get Service | Where Object{$\uu.Status-eq“Running”}您不能单独使用它Get Service,因为即使它输出的服务信息对象具有.BinaryPathName属性,该属性仅在PowerShell Core中可用,不一定是真正
查找正在运行的服务很容易:
Get Service | Where Object{$\uu.Status-eq“Running”}
您不能单独使用它Get Service
,因为即使它输出的服务信息对象具有.BinaryPathName
属性,该属性仅在PowerShell Core中可用,不一定是真正的服务二进制文件,它通常是由通用svchost.exe
服务主机托管的DLL
要在所有情况下查找二进制文件路径,您还必须(还)查询注册表中的服务定义。获得文件路径后,可以使用返回的文件信息对象的Get Item
和.VersionInfo
属性提取产品和公司名称等信息
底部的getservicefileinfo
函数就是这样做的;它允许您运行以下命令:
# Return information about all services that aren't part of Windows.
# (May still include Microsoft services).
Get-ServiceFileInfo | Where ProductName -ne 'Microsoft® Windows® Operating System'
Get-ServiceFileInfo
源代码(PSv5+,但可以调整为适用于较低版本):
#注意:虽然可以在没有提升权限的情况下运行,
#并不是所有的文件信息都可以检索。
#需要-运行管理员
函数Get ServiceFileInfo{
设置StrictMode-版本1
获取每个对象的服务| ForEach{
#仅限PowerShell核心:
#获取服务二进制路径,它可能是也可能不是真正的服务
#可执行文件。
$binaryPath=$\二进制路径名
#Windows PowerShell:
#我们转而尝试从注册表中获取“ImagePath”值。
#注意:即使在PowerShell Core中,似乎也存在获取服务失败的服务
#即使以管理员身份运行,也要进行查询,例如“SshdBroker”
#(发出非终止错误)。
#在这种情况下,也需要从注册表读取数据,
#但是,只有在以管理员身份运行时才能成功。
if(-not$binaryPath){
$binaryPath=尝试{Get-ItemPropertyValue-EA Ignore“HKLM:\SYSTEM\CurrentControlSet\Services\$($\ux.Name)”ImagePath}catch{}
}
#测试svchost.exe,这表明需要在别处查找特定于服务的DLL路径。
if($binaryPath-类似'*\svchost.exe*')){
#从注册表、子项“Parameters”和值“ServiceDLL”获取实际二进制文件(DLL)
#注意:某些服务存在于*2*(多个?)的化身中,如“”“和”\ux”
#只有“”化身具有“ServiceDLL”值,因此我们依赖于此。
foreach($\中的keyName,($\中的keyName-split'\')[0]){
#注意:大多数基于DLL的服务将“ServiceDLL”值存储在“Parameters”子项中,但
#有些在服务的根密钥本身中有。
foreach($keyName\Parameters中的subKeyName,$keyName){
$binaryPath=尝试{Get-ItemPropertyValue-EA Ignore“HKLM:\SYSTEM\CurrentControlSet\Services\$subKeyName”ServiceDLL}catch{}
if($binaryPath){break}
}
}
}
#清理路径:
#*有些值包含“…”,因此我们将其去掉,
#*其他人有争论,所以我们只接受第一个标记。
$binaryPath=if($binaryPath.StartsWith(“”)){
($binaryPath-split'')[1]
}否则{
#路径/命令行没有或没有以双引号标记开头,这
#可能意味着两件事之一:
#*它是一个基于无引号可执行文件的命令行,可能带有参数。
#*它是一个服务DLL路径-可能在(扩展)路径中有空格。
if(测试路径-LiteralPath$binaryPath-Type叶){
$binaryPath#值作为一个整体是一个文件路径
}否则{
(-split$binaryPath)[0]#值是一个命令行,提取可执行文件
}
}
$FileVersionInfo=if($binaryPath){(获取项-LiteralPath$binaryPath).VersionInfo}
#构造输出对象。
[pscustomobject]@{
名称=$\名称
BinaryPath=if($BinaryPath){$BinaryPath}else{(n/a);“写入错误”无法确定服务“$($.Name)”的二进制路径。请尝试以管理员身份运行。“”
ProductName=$FileVersionInfo.ProductName
FileDescription=$FileVersionInfo.FileDescription
CompanyName=$FileVersionInfo.CompanyName
}
}
}
我不知道这个问题的答案。我可以告诉你,不管怎样,我都将如何处理。我将查看从模板或映像部署的新版本上安装的服务,或者以其他方式部署新系统。然后我将新系统的get service
输出与系统I的输出进行比较n问题。
# Note: While it is possible to run without elevated privileges,
# not all file information is retrievable then.
#requires -runAsAdministrator
function Get-ServiceFileInfo {
Set-StrictMode -Version 1
Get-Service | ForEach-Object {
# PowerShell Core only:
# Get the service binary path, which may or may not be the true service
# executable.
$binaryPath = $_.BinaryPathName
# Windows PowerShell:
# We fall back on trying to obtain the "ImagePath" value from the registry.
# Note: Even in PowerShell Core there appear to be services that Get-Service fails
# to query even when running as admin, such as "SshdBroker"
# (a non-terminating error is issued).
# Reading from the registry is needed in that case too,
# but, only succeeds when running as admin.
if (-not $binaryPath) {
$binaryPath = try { Get-ItemPropertyValue -EA Ignore "HKLM:\SYSTEM\CurrentControlSet\Services\$($_.Name)" ImagePath } catch { }
}
# Test for svchost.exe, which indicates the need to look for the service-specific DLL path elsewhere.
if ($binaryPath -like '*\svchost.exe *') {
# Get the actual binary (DLL) from the registry, subkey "Parameters", value "ServiceDLL"
# NOTE: Some services exist in *2* (multiple?) incarnations, as "<name>"" and "<name>_<num>"
# Only the "<name>" incarnation has the "ServiceDLL" value, so we fall back on that.
foreach ($keyName in $_.Name, ($_.Name -split '_')[0]) {
# NOTE: Most DLL-based services store the "ServiceDLL" value in the "Parameters" subkey, but
# some have it in the service's root key itself.
foreach ($subKeyName in "$keyName\Parameters", $keyName) {
$binaryPath = try { Get-ItemPropertyValue -EA Ignore "HKLM:\SYSTEM\CurrentControlSet\Services\$subKeyName" ServiceDLL } catch { }
if ($binaryPath) { break }
}
}
}
# Sanitize the path:
# * Some values have enclosing "...", so we strip them,
# * others have arguments, so we only take the first token.
$binaryPath = if ($binaryPath.StartsWith('"')) {
($binaryPath -split '"')[1]
} else {
# The path / command line isn't or doesn't start with a double-quoted token, which
# can mean one of two things:
# * It is a command line based on an unquoted executable, possibly with arguments.
# * It is a service DLL path - possibly with spaces in the (expanded) path.
if (Test-Path -LiteralPath $binaryPath -Type Leaf) {
$binaryPath # Value as a whole is a file path
} else {
(-split $binaryPath)[0] # Value is a command line, extract executable
}
}
$FileVersionInfo = if ($binaryPath) { (Get-Item -LiteralPath $binaryPath).VersionInfo }
# Construct the output object.
[pscustomobject] @{
Name = $_.Name
BinaryPath = if ($binaryPath) { $binaryPath } else { '(n/a)'; Write-Error "Failed to determine binary path for service '$($_.Name)'. Try running as admin." }
ProductName = $FileVersionInfo.ProductName
FileDescription = $FileVersionInfo.FileDescription
CompanyName = $FileVersionInfo.CompanyName
}
}
}