關鍵是使用控制臺中顯示的 Powershell 物件的屬性名稱填充變數。這意味著,如果我運行Get-Process,我只希望在控制臺中回傳八個物件的屬性,它們是“Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName”。
Get-Member命令在這里沒有幫助。
任何人都可以幫助我嗎?
謝謝你們!
uj5u.com熱心網友回復:
要獲取為給定 .NET 型別呈現的表視圖的列名稱 (可能是也可能不是屬性名稱) ,如果它具有與之關聯的預定義格式資料(包括表視圖):
- 筆記:
- 以下是一個正確但重要且有限的解決方案,它使用找到的第一個表視圖定義從格式化資料中派生列名。它還具有概念性背景資訊。
- 有關僅獲取列名的快速而簡單的解決方案,請參閱底部部分,該解決方案使用文本決議直接從給定命令的格式化輸出中提取列名。
- 中間部分以第一部分為基礎,提取屬性名稱串列和反映列定義的計算屬性,可與 一起使用
Select-Object,以創建具有與格式化資料生成的相同值的屬性的自定義物件。
- 以下是一個正確但重要且有限的解決方案,它使用找到的第一個表視圖定義從格式化資料中派生列名。它還具有概念性背景資訊。
# Determine the .NET type of interest.
$type = (Get-Process)[0].GetType()
# Extract the names of the column headers from the *first* table-view definition.
Get-FormatData $type -PowerShellVersion $PSVersionTable.PSVersion |
ForEach-Object FormatViewDefinition |
Where-Object Control -is [System.Management.Automation.TableControl] |
Select-Object -First 1 |
ForEach-Object {
$i = 0
$rows = $_.Control.Rows
foreach ($colLabel in $_.Control.Headers.Label) {
if ($colLabel) { $colLabel } # Explicit label, with a calculated column value or renamed property
else { $rows.Columns[$i].DisplayEntry.Value } # Property name, with its value as the column value.
$i
}
}
警告:上述限制輸出到找到的第一個表視圖定義 - 這可能適用于也可能不適用于給定的命令。默認情況下選擇哪個定義可能由與基于運行時條件選擇的定義相關聯的標準控制,包括按特定輸入型別選擇,因為格式化資料的單個實體可以涵蓋多種型別。另請注意,視圖可能涉及分組(例如,正如您在Get-ChildItem的格式化輸出中看到的那樣),并且上述命令未涵蓋分組標準。
請注意,即使對于單一型別的多個視圖可以定義,并且為了使用非默認值,您必須通過Format-Table的-View引數明確請求它,假設您知道名稱,[1]例如Get-Process | Format-Table -View StartTime)。
- 也可以看看:
- 關于如何完整檢查格式化資料的這個答案。
- 您也可以通過管道
Get-FormatData輸出到Export-FormatData,以便將格式化資料匯出到 XML 檔案,這具有難以閱讀的缺點,但具有匹配用于創作格式化資料的 XML 模式的優點 - 請參閱下一點 - 而在 -用于表示格式化資料的記憶體型別部分使用與底層 XML 元素不匹配的屬性名稱。
- 您也可以通過管道
- As for authoring formatting data, which as of PowerShell 7.2.2 requires XML files (
*.Format.ps1xml):- See this answer for an example of how to define your own table view.
- Formatting File Overview and the Format Schema XML Reference
- 關于如何完整檢查格式化資料的這個答案。
Note:
Using
-PowerShellVersion $PSVersionTable.PSVersionwithGet-FormatDatais only needed in Windows PowerShell, for certain types, to work around a bug that is no longer present in PowerShell (Core) 7.1While column names typically correspond to the property names of the type instances being formatted, that isn't always the case, such as with the
[System.Diagnostics.Process]instances output byGet-Process.- A general caveat, as zett42 notes, is that display formatting of types isn't part of the public contract regarding breaking changes, so formatting definitions are allowed to change over time.
If a given type has no predefined formatting data associated with it (in which case
Get-FormatDatais a quiet no-op):The names of its (public) instance properties are used as column names.
You only get a table view by default if there are 4 or fewer properties but you can request it explicitly with
Format-Table(With 5 or more properties,Format-Listis applied by default).To get the names of all (public) instance properties of a given object, use the intrinsic
.psobjectproperty, which is a rich source of reflection; e.g.:(Get-Process | Select-Object -First 1).psobject.Properties.Name
To create a list of property names and calculated properties usable with Select-Object that mirror the formatting-data's column definition:
# Determine the .NET type of interest.
$type = (Get-Process)[0].GetType()
# Get an array of property names / calculated properties from the
# formatting data, for later use with Select-Object
$props =
Get-FormatData $type -PowerShellVersion $PSVersionTable.PSVersion |
ForEach-Object FormatViewDefinition |
Where-Object Control -Is [System.Management.Automation.TableControl] |
Select-Object -First 1 |
ForEach-Object {
$i = 0
$rows = $_.Control.Rows
foreach ($colLabel in $_.Control.Headers.Label) {
if ($colLabel) { # Explicit label, with a calculated column value or renamed property
@{
Name = $colLabel
Expression = if ('ScriptBlock' -eq $rows.Columns[$i].DisplayEntry.ValueType) {
[scriptblock]::Create($rows.Columns[$i].DisplayEntry.Value)
} else {
$rows.Columns[$i].DisplayEntry.Value
}
}
}
else { # Property name, with its value as the column value.
$rows.Columns[$i].DisplayEntry.Value
}
$i
}
}
# Sample call
Get-Process | Select-Object -Property $props | Format-Table | more
The sample call produces similar output to just
Get-Processalone, as it uses the column definitions as (calculated) properties - albeit with default values for formatting attributes such as column width and alignment.Note the explicit use of
Format-Tableto ensure tabular output; without it - given that the[pscustomobject]instances created bySelect-Objecthave no formatting data associated with them - list formatting (impliedFormat-List) would result.As Mathias points out, the calculated properties will be string-typed even for columns based on numeric properties, because their purpose in the formatting data is to created formatted string representations.
Quick-and-dirty solution for getting the column names only:
The following uses Out-String -Stream in conjunction with Select-String to extract the column names from a given command's formatted output, which relies on two assumptions:
- The column names have no embedded spaces
- The command actually produces table-formatted output by default; however, you can insert a
Format-Tablecall beforeOut-String, if desired.
Get-Process | Out-String -Stream | Select-String -List '^\s*-- ' -Context 1, 0 |
ForEach-Object { -split $_.Context.PreContext[0] }
Output:
NPM(K)
PM(M)
WS(M)
CPU(s)
Id
SI
ProcessName
Note: In Windows PowerShell an additional property shows, as the first one: Handles.
[1] While tab-completion does offer view names, they appear to be out of sync with the actually available ones, as of PowerShell 7.2.2. To see the latter, provoke an error with a dummy name, and the error message will list the available ones; e.g. Get-Process | Format-Table -View NoSuch lists the following available views in the resulting error message: process, Priority, StartTime
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/447644.html
