为什么从一个CmdLet输出的文本被格式化而从另一个CmdLet输出的文本却没有格式化?

问题描述 投票:0回答:1

我已经编写了2个cmdlet,用于在GUID和Oracle的Guid等效项之间进行转换,即它为用于存储GUID的RAW列显示的字符串。第一个Convert-GuidToRaw接受GUID字符串参数并输出原始字符串:

var raw = GuidConverter.Core.GuidConverter.ToRaw(Input);
WriteObject(raw);

raw的类型为string。当我运行此cmdlet时,我得到一个简单明了的字符串输出:

PS D:\SANRAL\NRA2> New-Guid | Convert-GuidToRaw                                                                  
DD8386EE09231A43B7731880CCAD6B87
PS D:\SANRAL\NRA2>

我的另一个cmdlet Convert-RawToGuid接受代表GUID的RAW字符串参数,并输出原始GUID:

var guid = GuidConverter.Core.GuidConverter.FromRaw(Input);
WriteObject(guid);

guid的类型为Guid。当我运行此cmdlet时,我得到的输出格式如表所示:

PS D:\SANRAL\NRA2> Convert-RawToGuid DD8386EE09231A43B7731880CCAD6B87

Guid
----
ee8683dd-2309-431a-b773-1880ccad6b87


PS D:\SANRAL\NRA2>

在两种情况下,我都输出单个对象,而不是列表,并且在两种情况下,该对象都可以用简单的字符串轻松表示。返回Guid类型时为什么会得到表格输出?

可能值得注意的是Convert-GuidToRaw cmdlet及其纯净的,未格式化的字符串输出,似乎无法正确写入管道。这两个cmdlet都从管道获取一个参数。我希望下面的此cmdlet管道可以输出GUID,而相反,管道中的最后一个cmdlet一直在寻找输入:

PS C:\WINDOWS\system32> New-Guid | Convert-GuidToRaw | Convert-RawToGuid

cmdlet Convert-RawToGuid at command pipeline position 3
Supply values for the following parameters:
Input:

为什么Convert-RawToGuid无法从Convert-GuidToRaw获得“流水线”字符串?交换管道的顺序如下所示,将导致预期的行为:

PS C:\WINDOWS\system32> Convert-RawToGuid F3BD9411DE8E4F4BBCACECFCED6D305D | Convert-GuidToRaw
F3BD9411DE8E4F4BBCACECFCED6D305D
PS C:\WINDOWS\system32>

Convert-RawToGuid cmdlet看起来像这样:

[Cmdlet(VerbsData.Convert, "RawToGuid")]
public class ConvertRawToGuidCommand : System.Management.Automation.Cmdlet
{
    [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true)]
    public string Input { get; set; }

    protected override void ProcessRecord()
    {
        if (string.IsNullOrEmpty(Input) || Input.Length != 32)
        {
            throw new ArgumentException("Input must be a 32 character hex string");
        }
        var guid = GuidConverter.Core.GuidConverter.FromRaw(Input);
        WriteObject(guid);
    }
}
powershell formatting powershell-5.0 cmdlets
1个回答
0
投票

在两种情况下,我都输出单个对象,而不是列表,并且在两种情况下,该对象都可以用简单的字符串轻松表示。返回Guid类型时,为什么会得到表格输出?

当交互式会话中的命令返回未分配的值时,PowerShell会将其传递给默认的Format Command以生成文本,然后再将其写入控制台。对于某些特定类型,PowerShell已预先配置了一堆“格式命令”,System.Guid是这些类型之一。

例如:

PS> [Guid]::NewGuid()

Guid
----
ee737b6f-7f68-4015-8841-1278b37a6420

[各种类型的默认格式化程序在PowerShell 5.1的* .Format.ps1xml文件中进行配置,并根据About Format.ps1xml从PowerShell 6起被烘焙到源代码中>

在PowerShell 5.1中,System.Guid的默认格式化程序配置可以在$PSHOME\DotNetTypes.format.ps1xml中找到,并且看起来像这样:

<View>
  <Name>System.Guid</Name>
  <ViewSelectedBy>
    <TypeName>System.Guid</TypeName>
  </ViewSelectedBy>
  <TableControl>
    <TableRowEntries>
      <TableRowEntry>
        <TableColumnItems>
          <TableColumnItem>
            <PropertyName>Guid</PropertyName>
          </TableColumnItem>
        </TableColumnItems>
      </TableRowEntry>
    </TableRowEntries>
  </TableControl>
</View>

所以您得到的表只有一个包含Guid属性的列。

如果执行此操作,您将获得完全相同的结果:

PS> [Guid]::NewGuid() | Format-Table -Property "Guid"

Guid
----
ee737b6f-7f68-4015-8841-1278b37a6420

并且如果您想将default

格式化命令的结果捕获到字符串变量中(例如,写入日志文件),则可以执行此操作:
PS> $text = [Guid]::NewGuid() | Out-String
PS> $text

Guid
----
ee737b6f-7f68-4015-8841-1278b37a6420

为什么Convert-RawToGuid无法从Convert-GuidToRaw获得“流水线”字符串?交换管道的顺序如下所示,将导致预期的行为:

很难看到您没有实现Convert-RawToGuid的情况。例如,以下内容对我适用:

function Convert-StringToGuid
{
    param( [string] $Input )
    return new-object Guid($Input);
}

function Convert-GuidToString
{
    param( $Input )
    return $Input.Guid;
}

(new-object Guid("d12cd880-29d5-42c6-b45e-5411f57c880c")) | Convert-GuidToString | Convert-StringToGuid

"d12cd880-29d5-42c6-b45e-5411f57c880c" | Convert-StringToGuid | Convert-GuidToString

带有输出:


Guid
----
d12cd880-29d5-42c6-b45e-5411f57c880c


d12cd880-29d5-42c6-b45e-5411f57c880c
© www.soinside.com 2019 - 2024. All rights reserved.