如何以特定方式格式化Powershell输出?

如何以特定方式格式化Powershell输出?,powershell,Powershell,我需要扫描我的网络以查找服务器上的特定进程。我已经完成了以下脚本: 28..31 | ForEach-Object { Get-Process -ComputerName "192.168.0.$_" -Name svc* } 现在,我如何格式化输出,使其显示在哪个IP地址找到的过程中显示?多谢各位 这里有一种方法可以完成这项工作。[咧嘴笑]它的作用 构建ip最终八位字节范围 设置IPv4基本八位字节 生成要搜索的进程列表 设置“无响应”文本 在第四个八位组范围内迭代 生成IPv4地址 检查

我需要扫描我的网络以查找服务器上的特定进程。我已经完成了以下脚本:

28..31 | ForEach-Object { Get-Process -ComputerName "192.168.0.$_" -Name svc* }

现在,我如何格式化输出,使其显示在哪个IP地址找到的过程中显示?多谢各位

这里有一种方法可以完成这项工作。[咧嘴笑]它的作用

  • 构建ip最终八位字节范围
  • 设置IPv4基本八位字节
  • 生成要搜索的进程列表
  • 设置“无响应”文本
  • 在第四个八位组范围内迭代
  • 生成IPv4地址
  • 检查它是否在线/正在响应
  • 如果是,则获取主机名
    对于我的PoSh[win7,ps5.1]版本,
    Get-Process
    cmdlet将不接受ip地址。需要主机名
  • 更正使用ATT进行inet服务时返回的损坏主机名
  • 创建用于构建属性列表的有序哈希表
  • 根据需要构建各种道具
  • 将哈希表转换为
    PSCustomObject
  • 将其发送到
    $Results
    集合
  • 在屏幕上显示它
  • 将其发送到CSV文件
这是密码

$4thOctetRange = 64..66
$IpBase = '192.168.1'

$ProcessList = @(
    'AutoHotKey'
    'BetterNotBeThere'
    'DisplayFusion'
    'Foobar2000'
    )

$NoResponse = '__n/a__'

$Results = foreach ($4OR_Item in $4thOctetRange)
    {
    $Ip = '{0}.{1}' -f $IpBase, $4OR_Item

    $Online = Test-Connection -ComputerName $Ip -Count 1 -Quiet
    if ($Online)
        {
        # getting the hostname is REQUIRED by my version of Get-Process
        #    it will not accept an IP address
        #    version info = win7, ps5.1
        # this may need adjusting for your returned hostname
        #    mine shows Hostname.attlocal.net
        #    that is not valid with any query i make, so i removed all after the 1st dot
        $HostName = ([System.Net.Dns]::GetHostByAddress($Ip)).HostName.Split('.')[0]
        }
        else
        {
        $HostName = $NoResponse
        }

    $TempProps = [ordered]@{}
    $TempProps.Add('IpAddress', $Ip)
    $TempProps.Add('Online', $Online)
    $TempProps.Add('HostName', $HostName)
    foreach ($PL_Item in $ProcessList)
        {
        if ($TempProps['Online'])
            {
            # if the process aint found, the "SilentlyContinue" forces a $Null
            #    the "[bool]" then coerces that to a "False"
            $TempProps.Add($PL_Item, [bool](Get-Process -ComputerName $HostName -Name $PL_Item -ErrorAction SilentlyContinue))
            }
            else
            {
            $TempProps.Add($PL_Item, $NoResponse)
            }
        }

    # send the object out to the $Results collection
    [PSCustomObject]$TempProps
    }

# send to screen
$Results

# send to CSV file    
$Results |
    Export-Csv -LiteralPath "$env:TEMP\Senator14_RemoteProcessFinder.csv"  -NoTypeInformation
截短的屏幕输出

IpAddress        : 192.168.1.65
Online           : True
HostName         : ZK_01
AutoHotKey       : True
BetterNotBeThere : False
DisplayFusion    : True
Foobar2000       : True

IpAddress        : 192.168.1.66
Online           : False
HostName         : __n/a__
AutoHotKey       : __n/a__
BetterNotBeThere : __n/a__
DisplayFusion    : __n/a__
Foobar2000       : __n/a__
csv文件内容

"IpAddress","Online","HostName","AutoHotKey","BetterNotBeThere","DisplayFusion","Foobar2000"
"192.168.1.64","False","__n/a__","__n/a__","__n/a__","__n/a__","__n/a__"
"192.168.1.65","True","ZK_01","True","False","True","True"
"192.168.1.66","False","__n/a__","__n/a__","__n/a__","__n/a__","__n/a__"

这里有一种方法可以完成这项工作。[咧嘴笑]它的作用

  • 构建ip最终八位字节范围
  • 设置IPv4基本八位字节
  • 生成要搜索的进程列表
  • 设置“无响应”文本
  • 在第四个八位组范围内迭代
  • 生成IPv4地址
  • 检查它是否在线/正在响应
  • 如果是,则获取主机名
    对于我的PoSh[win7,ps5.1]版本,
    Get-Process
    cmdlet将不接受ip地址。需要主机名
  • 更正使用ATT进行inet服务时返回的损坏主机名
  • 创建用于构建属性列表的有序哈希表
  • 根据需要构建各种道具
  • 将哈希表转换为
    PSCustomObject
  • 将其发送到
    $Results
    集合
  • 在屏幕上显示它
  • 将其发送到CSV文件
这是密码

$4thOctetRange = 64..66
$IpBase = '192.168.1'

$ProcessList = @(
    'AutoHotKey'
    'BetterNotBeThere'
    'DisplayFusion'
    'Foobar2000'
    )

$NoResponse = '__n/a__'

$Results = foreach ($4OR_Item in $4thOctetRange)
    {
    $Ip = '{0}.{1}' -f $IpBase, $4OR_Item

    $Online = Test-Connection -ComputerName $Ip -Count 1 -Quiet
    if ($Online)
        {
        # getting the hostname is REQUIRED by my version of Get-Process
        #    it will not accept an IP address
        #    version info = win7, ps5.1
        # this may need adjusting for your returned hostname
        #    mine shows Hostname.attlocal.net
        #    that is not valid with any query i make, so i removed all after the 1st dot
        $HostName = ([System.Net.Dns]::GetHostByAddress($Ip)).HostName.Split('.')[0]
        }
        else
        {
        $HostName = $NoResponse
        }

    $TempProps = [ordered]@{}
    $TempProps.Add('IpAddress', $Ip)
    $TempProps.Add('Online', $Online)
    $TempProps.Add('HostName', $HostName)
    foreach ($PL_Item in $ProcessList)
        {
        if ($TempProps['Online'])
            {
            # if the process aint found, the "SilentlyContinue" forces a $Null
            #    the "[bool]" then coerces that to a "False"
            $TempProps.Add($PL_Item, [bool](Get-Process -ComputerName $HostName -Name $PL_Item -ErrorAction SilentlyContinue))
            }
            else
            {
            $TempProps.Add($PL_Item, $NoResponse)
            }
        }

    # send the object out to the $Results collection
    [PSCustomObject]$TempProps
    }

# send to screen
$Results

# send to CSV file    
$Results |
    Export-Csv -LiteralPath "$env:TEMP\Senator14_RemoteProcessFinder.csv"  -NoTypeInformation
截短的屏幕输出

IpAddress        : 192.168.1.65
Online           : True
HostName         : ZK_01
AutoHotKey       : True
BetterNotBeThere : False
DisplayFusion    : True
Foobar2000       : True

IpAddress        : 192.168.1.66
Online           : False
HostName         : __n/a__
AutoHotKey       : __n/a__
BetterNotBeThere : __n/a__
DisplayFusion    : __n/a__
Foobar2000       : __n/a__
csv文件内容

"IpAddress","Online","HostName","AutoHotKey","BetterNotBeThere","DisplayFusion","Foobar2000"
"192.168.1.64","False","__n/a__","__n/a__","__n/a__","__n/a__","__n/a__"
"192.168.1.65","True","ZK_01","True","False","True","True"
"192.168.1.66","False","__n/a__","__n/a__","__n/a__","__n/a__","__n/a__"

我建议切换到,因为:

  • 它提供了一个远程执行任何命令的框架,而不是依赖单个cmdlet来支持
    -ComputerName
    参数,并使用防火墙友好的传输

  • PowerShell[Core]v6+将继续支持它,不再支持cmdlet单个参数
    -ComputerName
    参数;此过时的远程处理方法使用的是一种较旧的、不太适合防火墙的远程处理形式,而-Observed-since v3-WMI cmdlet也使用这种形式(后者被CIM cmdlet取代)

因此,最好将防火墙友好型PowerShell远程处理与其通用远程处理命令(
Invoke Command
Enter-PSSession
,…)一致使用

如果使用
调用命令
以目标(多台)远程计算机为目标,则返回的对象将通过自动添加的
.PSComputerName
属性自动包含并显示原始计算机的名称

# Create the array of IP addresses to target:
$ips = 28..31 -replace '^', '192.168.0.'

# Use a *single* Invoke-Command call to target *all* computers at once.
# Note: The results will typically *not* reflect the input order of
#       given IPs / computer names.
Invoke-Command -ComputerName $ips { Get-Process -Name svc* }
您将看到如下输出-注意
PSComputerName
列:

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName  PSComputerName
-------  ------    -----      -----     ------     --  -- -----------  --------------
   1013      18     7464      13732      52.72      8   0 svchost      192.168.0.30
...
请注意,您可以使用
调用命令
-HideComputerName
参数
禁止自动显示
.PSComputerName
属性。 但是,该属性仍然以编程方式可用,这允许您执行以下操作:

Invoke-Command -ComputerName $ips { Get-Process -Name svc* } -HideComputerName |
  Format-Table -GroupBy PSComputerName
这将产生按计算机名/IP分组的显示输出:


   PSComputerName: 192.168.0.30

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
   1013      18     7464      13732      52.72      8   0 svchost    
...


   PSComputerName: 192.168.0.28

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
   1007      17     7112      12632      65.45     11   0 svchost    
...
如果要在分组之前按IP地址进行排序,可以在调用
格式表之前插入
|sort Object{[version]$.PSComputerName}
[1] 对于按计算机名排序的,只需
|排序对象PSComputerName
就可以了



[1] 转换到
[version]
是确保IP地址正确排序的技巧;IP地址字符串可以解释为
[version]
System.version
)实例,这些实例可以直接比较,使用版本组件的数值(首先是
.MajorVersion
,然后是
.MinorVersion
,…)

我建议切换到,因为:

  • 它提供了一个远程执行任何命令的框架,而不是依赖单个cmdlet来支持
    -ComputerName
    参数,并使用防火墙友好的传输

  • PowerShell[Core]v6+将继续支持它,不再支持cmdlet单个参数
    -ComputerName
    参数;此过时的远程处理方法使用的是一种较旧的、不太适合防火墙的远程处理形式,而-Observed-since v3-WMI cmdlet也使用这种形式(后者被CIM cmdlet取代)

因此,最好将防火墙友好型PowerShell远程处理与其通用远程处理命令(
Invoke Command
Enter-PSSession
,…)一致使用

如果使用
调用命令
以目标(多台)远程计算机为目标,则返回的对象将通过自动添加的
.PSComputerName
属性自动包含并显示原始计算机的名称

# Create the array of IP addresses to target:
$ips = 28..31 -replace '^', '192.168.0.'

# Use a *single* Invoke-Command call to target *all* computers at once.
# Note: The results will typically *not* reflect the input order of
#       given IPs / computer names.
Invoke-Command -ComputerName $ips { Get-Process -Name svc* }
您将看到如下输出-注意
PSComputerName
列:

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName  PSComputerName
-------  ------    -----      -----     ------     --  -- -----------  --------------
   1013      18     7464      13732      52.72      8   0 svchost      192.168.0.30
...
请注意,您可以使用
Invoke命令的
-HideCo来抑制
.PSComputerName
属性的自动显示