AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 722526
Accepted
Caynadian
Caynadian
Asked: 2015-09-16 10:57:33 +0800 CST2015-09-16 10:57:33 +0800 CST 2015-09-16 10:57:33 +0800 CST

以表格形式强制输出 Powershell 脚本

  • 772

是否有强制将 PowerShell v3 脚本的输出转换为表格形式?我的脚本以线性形式输出服务列表,即使输出对象中只有 6 个字段(get-process 以表格形式输出 8 个字段)。这是我的代码:

<#
.SYNOPSIS
Gets a list of services on a given computer that are supposed to automatically start but are not currently running.
.PARAMETER ComputerName
The computer name(s) to retrieve the info from.
.PARAMETER IgnoreList
The path and filename of a text file containing a list of service names to ignore.  This file has to list actual service names and not display names.  Defaults to "StoppedServices-Ignore.txt" in the current directory.
.PARAMETER StartServices
Optional switch that when specified will cause this function to attempt to start all of the services it finds stopped.
.EXAMPLE
Get-StoppedServices -ComputerName Computer01 -IgnoreList '.\IgnoredServices.txt' -StartServices
.EXAMPLE
Get-StoppedServices –ComputerName Computer01,Computer02,Computer03
.EXAMPLE
"Computer01" | Get-StoppedServices
.EXAMPLE
Get-StoppedServices –ComputerName (Get-Content ComputerList.txt)
.EXAMPLE
Get-Content ComputerList.txt | Get-StoppedServices -IgnoreList '.\IgnoredServices.txt' -StartServices
#>
Function Get-StoppedServices {
  [CmdletBinding()]
  param(
    [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [String[]]$ComputerName,
    [string]$IgnoreList,
    [switch]$StartServices
  )
  PROCESS {
    # Load the list of services to ignore (if specified).
    if ($IgnoreList) {
      if (Test-Path $IgnoreList) {
        $ignore = import-csv -header Service $IgnoreList
        Write-Verbose "Ignoring the following services:"
        Write-Verbose $ignore.ToString()
      } else {
        Write-Warning "Could not find ignore list $IgnoreList."
      }
    }

    # Get a list of stopped services that are set to run automatically (ie: that should be running)
    foreach ($c in $ComputerName) {
      Write-Verbose "Getting services from $($c.Name)"
      if (Test-Connection -ComputerName $c -Count 1 -Quiet) {
        Try {
          $serv += get-wmiobject -query "Select __Server,Name,DisplayName,State,StartMode,ExitCode,Status FROM Win32_Service WHERE StartMode='Auto' AND State!='Running'" -computername $c -erroraction stop
        } catch {
          Write-Warning "Could not get service list from $($c)"
        }
      }
    }

    # Create the resulting list of services by removing any that are in the ignore list.
    $results = @()
    foreach ($s in $serv) {
      Write-Verbose "Checking if $($s.name) in ignore list."
      if ($ignore -match $s.name) { 
        Write-Verbose "  *Service in ignore list."
      } else {
        Write-Verbose "  Service OK."
        $obj = New-Object -typename PSObject
        $obj | Add-Member -membertype NoteProperty -name ComputerName -value ($s.PSComputerName) -passthru |
               Add-Member -membertype NoteProperty -name ServiceName  -value ($s.Name)           -passthru |
               Add-Member -membertype NoteProperty -name DisplayName  -value ($s.DisplayName)    -passthru |
               Add-Member -membertype NoteProperty -name Status       -value ($s.Status)         -passthru |
               Add-Member -membertype NoteProperty -name State        -value ($s.State)          -passthru |
               Add-Member -membertype NoteProperty -name ExitCode     -value ($s.ExitCode)
        $results += $obj
      }
    }

    # Try and start each of the stopped services that hasn't been ignored.
    if ($StartServices) {
      foreach ($s in $results) {
        Write-Verbose "Starting '$($s.DisplayName)' ($($s.name)) on '$($s.ComputerName)..."
        Try {
          Get-Service -Name $s.name -ComputerName $s.ComputerName -erroraction stop | Start-service -erroraction stop
        } Catch {
          Write-Warning "Could not start service $($s.name) on $($s.ComputerName)."
        }
      }  
    }

    # Output the list of filtered services to the pipeline.
    write-output $results
  }
}
powershell
  • 1 1 个回答
  • 1208 Views

1 个回答

  • Voted
  1. Best Answer
    Mathias R. Jessen
    2015-09-21T07:23:25+08:002015-09-21T07:23:25+08:00

    当一个或多个对象冒泡到主机时,PowerShell 会查看对象具有的属性数量。

    如果可以将对象的类型解析为相应的Format.ps1xml文件(我们将在稍后讨论),则将使用该文档中描述的格式约定 - 否则,它取决于对象具有的属性数量。


    如果一个对象的属性少于 5 个,则默认Format-Table用于输出格式:

    PS C:\> New-Object psobject -Property ([ordered]@{PropA=1;PropB=2;PropC=3;PropD=4})
    
    PropA PropB PropC PropD
    ----- ----- ----- -----
        1     2     3     4
    

    如果一个对象有更多的属性,它默认为Format-List(这是你所经历的):

    PS C:\> New-Object psobject -Property ([ordered]@{PropA=1;PropB=2;PropC=3;PropD=4;PropE=5})
    
    
    PropA : 1
    PropB : 2
    PropC : 3
    PropD : 4
    PropE : 5
    

    现在,从Get-Serviceor Get-Processcmdlet 返回的对象似乎格式化为一个漂亮的、上下文相关的、超过 5 个列表的原因是 PowerShell 能够为它们找到一个特定于类型的格式化文档。

    这些格式化文件都位于 PowerShell 安装目录中,您可以使用以下命令找到默认文件:

    Get-ChildItem $PSHome *.Format.ps1xml
    

    看看Get-Help about_Format.ps1xml您是否要创建自己的格式文件。


    PowerShell 在对象类型和定义的格式视图之间建立链接的方式是检查 hiddenpstypenames属性:

    PS C:\> $obj.pstypenames
    System.Management.Automation.PSCustomObject
    System.Object
    

    PowerShell 只是钻取这个祖先的类型列表,以查看它是否具有所述类型的相应格式视图。

    这意味着您可以欺骗 PowerShell 将对象格式化为其他类型,而无需实际干预底层 .NET 类型系统。

    为了展示这一点,让我们创建一个虚假的服务控制器 - 一个看起来像是Get-Service可以返回的对象,但实际上不是:

    PS C:\> $FauxService = New-Object psobject -Property @{
    >>>   "Name"        = "FakeService3000"
    >>>   "Status"      = "Faking"
    >>>   "DisplayName" = "TrustworthyService"
    >>>   "TrueName"    = "Really a fake"
    >>>   "Author"="Clever Genius"
    >>> }
    PS C:\> $FauxService
    
    
    Status      : Faking
    Name        : FakeService3000
    Author      : Clever Genius
    DisplayName : TrustworthyService
    TrueName    : Really a fake
    

    如上所述,PowerShell 显示了我们的输出,Format-List因为我们psobject有 5 个属性。

    现在,让我们尝试注入一个类型名称:

    PS C:\> $FauxService.pstypenames.Insert(0,"System.ServiceProcess.ServiceController")
    PS C:\> $FauxService
    
    Status   Name               DisplayName
    ------   ----               -----------
    Faking   FakeService3000    TrustworthyService
    

    瞧!

    • 5

相关问题

  • 资源锁和电源外壳

  • 脚本 - 如何断开远程桌面会话?

  • 如何限制向通讯组发送到外部地址?

  • Powershell对值与数组的作用不同?

  • Windows Powershell Vim 键绑定

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve