是否有强制将 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 会查看对象具有的属性数量。
如果可以将对象的类型解析为相应的
Format.ps1xml
文件(我们将在稍后讨论),则将使用该文档中描述的格式约定 - 否则,它取决于对象具有的属性数量。如果一个对象的属性少于 5 个,则默认
Format-Table
用于输出格式:如果一个对象有更多的属性,它默认为
Format-List
(这是你所经历的):现在,从
Get-Service
orGet-Process
cmdlet 返回的对象似乎格式化为一个漂亮的、上下文相关的、超过 5 个列表的原因是 PowerShell 能够为它们找到一个特定于类型的格式化文档。这些格式化文件都位于 PowerShell 安装目录中,您可以使用以下命令找到默认文件:
看看
Get-Help about_Format.ps1xml
您是否要创建自己的格式文件。PowerShell 在对象类型和定义的格式视图之间建立链接的方式是检查 hidden
pstypenames
属性:PowerShell 只是钻取这个祖先的类型列表,以查看它是否具有所述类型的相应格式视图。
这意味着您可以欺骗 PowerShell 将对象格式化为其他类型,而无需实际干预底层 .NET 类型系统。
为了展示这一点,让我们创建一个虚假的服务控制器 - 一个看起来像是
Get-Service
可以返回的对象,但实际上不是:如上所述,PowerShell 显示了我们的输出,
Format-List
因为我们psobject
有 5 个属性。现在,让我们尝试注入一个类型名称:
瞧!