我想为PowerShell函数的输出建议一种特定的格式(也许是强制的,但我对语义还不太确定)。
Format.ps1xml ( PowerShell 7.1版本)说:“从PowerShell 6开始,默认视图在PowerShell源代码中定义。PowerShell 5.1和早期版本的Format.ps1xml文件在PowerShell 6和更高版本中不存在。”本文接着解释了如何使用Format.ps1xml文件来更改对象的显示等等。这一点并不十分明确:‘不存在’-ne‘不能存在’.
这就引出了几个问题:
例如,Get-ADUser
cmdlet返回由Format-List
格式化的对象。如果我编写了一个名为Search-ADUser
的函数,该函数在内部调用Get-ADUser
并返回其中的一些对象,则输出也将格式化为list。在返回之前将输出传递到Format-Table
并不满足我的要求,因为输出将不会在管道中被视为单独的对象。
示例代码:
function Search-ADUser {
param (
$Name,
[ValidateNotNullOrEmpty()][string[]]$Properties = @('Enabled', 'SamAccountName', 'Name', 'emailAddress', 'proxyAddresses')
)
return Get-ADUser -Filter ('name -like "*{0}*"' -F $Name) -Properties $Properties | Select-Object $Properties
}
最好的答案应该解决这两个问题,尽管第二个问题更突出。
不可接受的答案包括建议该函数不应强制执行格式,和/或用户应将函数的输出输送到他们选择的格式化程序。这是一种非常主观的立场,它是否为多数人所持有,与问题无关。
我在发帖之前搜索了force function format #powershell-7.0
,但搜索结果似乎都与此无关。
发布于 2021-06-15 17:45:18
尽管
Format.ps1xml
文件“不存在”,但是否可以在大于5.1的PowerShell版本中创建/使用它们?
- That `*.ps1xml` _files_ are invariably needed for such definitions is unfortunate; [GitHub issue #7845](https://github.com/PowerShell/PowerShell/issues/7845) asks for an in-memory, API-based alternative (which for _type_ data already exists, via the [`Update-TypeData`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/update-typedata) cmdlet).
- However, in the context of [_modules_](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Modules), the need for files is less inconvenient, as they can be bundled with the module and are automatically loaded when referenced from the [module manifest](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Module_Manifests)'s `FormatsToProcess` entry.
是否有更好的做法向PowerShell建议某个函数应该如何格式化返回的数据?
由于缺乏基于API的格式数据定义方法,需要采用以下方法:
- If it is `[pscustomobject]` instances that the formatting should apply to, you need to (a) _choose_ a unique (virtual) type name and (b) assign it to the `[pscustomobject]` instances via PowerShell's [ETS (Extended Type System)](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Types.ps1xml); e.g.:
- For `[pscustomobject]` instances created by the [`Select-Object`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/select-object) cmdlet:
将虚拟类型名称"MyVirtualType“分配给对象输出#:Select ChildItem *.txt *.txt Select名称,长度为ForEach-Object { $_.pstypenames.Insert(0,'MyVirtualType');$_ }
- For `[pscustomobject]` _literals_, specify the type name via a `PSTypeName` entry:
pscustomobject @{ PSTypeName = 'MyVirtualType‘foo =1 bar =2}
*.ps1mxl
文件并将其加载到每个会话中。- If the commands that rely on this formatting data are defined in a _module_, you can incorporate the file into your module so that it is automatically automatically when the module is imported.
- For help on authoring such files, see:
- [Formatting File Overview](https://learn.microsoft.com/en-us/powershell/scripting/developer/format/formatting-file-overview)
- [Format XML Reference](https://learn.microsoft.com/en-us/powershell/scripting/developer/format/format-schema-xml-reference)
GitHub提案#10463要求提供一种大大简化的体验,支持指定所需格式的扩展[OutputType()]
属性。
应用于示例函数
*.ps1xml
文件,以确保为所有5个属性(默认情况下,5个或更多属性导致(隐式) Format-List
格式设置)应用(隐式)Format-List
格式设置。- As you can see, creating the XML for the formatting definitions is verbose and cumbersome, even without additional settings, such as column width and alignment.
- A better, but more elaborate solution would be to package your function in a [_module_](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Modules) into whose folder you can place the `*.ps1mxl` file (e.g., `SearchAdUserResult.Format.ps1xml`) and then instruct PowerShell to load the file on module import, via the `FormatsToProcess` key in the [module manifest](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/new-modulemanifest) (`*.psd1`) - e.g., `FormatsToProcess = 'SearchAdUserResult.Format.ps1xml'`
*.ps1mxl
输出的Microsoft.ActiveDirectory.Management.ADUser
实例直接创建Get-ADUser
文件,但这样做会将格式化会话应用于任何发出此类对象的命令。function Search-ADUser {
param (
$Name,
[ValidateNotNullOrEmpty()][string[]]$Properties = @('Enabled', 'SamAccountName', 'Name', 'emailAddress', 'proxyAddresses')
)
# The self-chosen ETS type name.
$etsTypeName = 'SearchAdUserResult'
# Create the formatting data on demand.
if (-not (Get-FormatData -ErrorAction Ignore $etsTypeName)) {
# Create a temporary file with formatting definitions to pass to
# Update-FormatData below.
$tempFile = Join-Path ([IO.Path]::GetTempPath()) "$etsTypeName.Format.ps1xml"
# Define a table view with all 5 properties.
@"
<Configuration>
<ViewDefinitions>
<View>
<Name>$etsTypeName</Name>
<ViewSelectedBy>
<TypeName>$etsTypeName</TypeName>
</ViewSelectedBy>
<TableControl>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Enabled</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>SamAccountName</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>emailAddress</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>proxyAddresses</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
"@ > $tempFile
# Load the formatting data into the current session.
Update-FormatData -AppendPath $tempFile
# Clean up.
Remove-Item $tempFile
}
# Call Get-ADUser and assign the self-chosen ETS type name to the the output.
# Note: To test this with a custom-object literal, use the following instead of the Get-ADUser call:
# [pscustomobject] @{ Enabled = $true; SamAccountName = 'jdoe'; Name = 'Jane Doe'; emailAddress = 'jdoe@example.org'; proxyAddresses = 'janedoe@example.org' }
Get-ADUser -Filter ('name -like "*{0}*"' -F $Name) -Properties $Properties | Select-Object $Properties | ForEach-Object {
$_.pstypenames.Insert(0, $etsTypeName); $_
}
}
然后,您将看到所需的基于格式数据的表格输出;例如:
Enabled SamAccountName Name emailAddress proxyAddresses
------- -------------- ---- ------------ --------------
True jdoe Jane Doe jdoe@example.org janedoe@example.org
https://stackoverflow.com/questions/67990004
复制相似问题