Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 为什么一个CmdLet的文本输出是格式化的,而另一个CmdLet的文本输出不是格式化的?_Powershell_Formatting_Powershell 5.0_Cmdlets - Fatal编程技术网

Powershell 为什么一个CmdLet的文本输出是格式化的,而另一个CmdLet的文本输出不是格式化的?

Powershell 为什么一个CmdLet的文本输出是格式化的,而另一个CmdLet的文本输出不是格式化的?,powershell,formatting,powershell-5.0,cmdlets,Powershell,Formatting,Powershell 5.0,Cmdlets,我已经编写了两个cmdlet,用于在Guid和Oracle的等效Guid之间进行转换,即它为用于存储Guid的原始列显示的字符串。第一个,Convert GuidToRaw,接受GUID字符串param并输出原始字符串: var raw = GuidConverter.Core.GuidConverter.ToRaw(Input); WriteObject(raw); 其中raw具有类型string。运行此cmdlet时,我会得到一个简单的字符串输出: PS D:\SANRAL\NRA2>

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

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的原始字符串参数并输出原始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);
    }
}
[Cmdlet(VerbsData.Convert, "GuidToRaw")]
public class ConvertGuidToRawCommand : System.Management.Automation.Cmdlet
{
    [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true)]
    public Guid Input { get; set; }

    protected override void ProcessRecord()
    {
        var raw = GuidConverter.Core.GuidConverter.ToRaw(Input);
        WriteObject(raw);
    }
}
<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>
Convert-GuidToRaw
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);
    }
}
[Cmdlet(VerbsData.Convert, "GuidToRaw")]
public class ConvertGuidToRawCommand : System.Management.Automation.Cmdlet
{
    [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true)]
    public Guid Input { get; set; }

    protected override void ProcessRecord()
    {
        var raw = GuidConverter.Core.GuidConverter.ToRaw(Input);
        WriteObject(raw);
    }
}
<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>

第1部分

在这两种情况下,我都输出一个对象,而不是一个列表,并且在这两种情况下,对象都很容易用一个简单的字符串表示。为什么在返回Guid类型时会得到表格输出

当交互会话中的命令返回未分配的值时,PowerShell会将其传递给默认值以在写入控制台之前生成文本。PowerShell预先配置了一些特定类型的格式化命令,并且是这些类型中的一种

例如:

PS>[Guid]::NewGuid()
指南
----
ee737b6f-7f68-4015-8841-1278b37a6420
各种类型的默认格式化程序在PowerShell 5.1中的*.Format.ps1xml文件中进行配置,并按照从PowerShell 6开始烘焙到源代码中

在PowerShell 5.1中,System.Guid的默认格式化程序配置可以在
$PSHOME\dotnetypes.format.ps1xml
中找到,如下所示:

[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);
    }
}
[Cmdlet(VerbsData.Convert, "GuidToRaw")]
public class ConvertGuidToRawCommand : System.Management.Automation.Cmdlet
{
    [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true)]
    public Guid Input { get; set; }

    protected override void ProcessRecord()
    {
        var raw = GuidConverter.Core.GuidConverter.ToRaw(Input);
        WriteObject(raw);
    }
}
<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>
如果要将默认格式化命令的结果捕获到字符串变量中(例如写入日志文件),可以执行以下操作:

PS>$text=[Guid]::NewGuid()|输出字符串
PS>$text
指南
----
ee737b6f-7f68-4015-8841-1278b37a6420
第二部分

为什么Convert-RawToGuid不能从Convert-GuidToRaw获取“管道化”字符串?按如下方式交换管道顺序,会导致预期行为:

PS C:\WINDOWS\system32> Convert-RawToGuid F3BD9411DE8E4F4BBCACECFCED6D305D | Convert-GuidToRaw
F3BD9411DE8E4F4BBCACECFCED6D305D
PS C:\WINDOWS\system32>
我无法重现您的问题,但以下内容对我很有用(需要注意的是,我找不到具有类
GuidConverter.Core.GuidConverter
的库,所以我假设它是一个私有实现,我使用默认字符串fomat代替它-例如:“024673b5-9c65-447a-be87-dae5f11f5142”)。您可以在本地尝试,看看是否得到相同的结果或您报告的问题,然后从那里开始

  • 在Visual Studio中使用.Net Framework 4.7.2创建新的C#类库解决方案
  • 添加对Microsoft.PowerShell.5.1.ReferenceAssembles NuGet包的引用
  • 将以下代码添加到新类文件中并生成项目:
使用系统;
使用系统、管理、自动化;
命名空间MyCmdlet
{
[Cmdlet(VerbsData.Convert,“RawToGuid”)]
公共类ConvertRawToGuidCommand:Cmdlet
{
[参数(必需=真,位置=1,ValueFromPipeline=真)]
公共字符串输入{get;set;}
受保护的覆盖无效ProcessRecord()
{
if(string.IsNullOrEmpty(this.Input)| | this.Input.Length!=36)
{
抛出新ArgumentException(“输入必须是36个字符的十六进制字符串”);
}
var guid=新的guid(this.Input);
WriteObject(guid);
}
}
[Cmdlet(VerbsData.Convert,“GuidToRaw”)]
公共类ConvertGuidToRawCommand:Cmdlet
{
[参数(必需=真,位置=1,ValueFromPipeline=真)]
公共Guid输入{get;set;}
受保护的覆盖无效ProcessRecord()
{
var raw=this.Input.ToString();
WriteObject(原始);
}
}
}
如果我构建此代码,我可以从PowerShell引用它,并且以下代码可以正常工作:

PS> Import-Module ".\MyCmdlet.dll"
PS> New-Guid | Convert-GuidToRaw | Convert-RawToGuid

Guid
----
15591624-44c9-4c55-acd7-22b7a2d0bee0

感谢您提供有关格式设置的所有信息。我在问题中添加了我的
Convert RawToGuid
实现。这是C#而不是PowerShell脚本。有趣的是,您使用.NET调用来获取新的GUID,其中我有一个
new GUID
cmdlet,它似乎是内置的。@ProfK-re[GUID]::NewGuid-我来自C#背景-默认情况下我倾向于下拉到.NET类:-)。我也来自一个较长的C#背景,但是我总是忘记在PS中使用.Net类有多么容易。谢谢你的提醒。你也可以发布转换GuidToRaw的代码吗?我应该想在转换RawToGuid的同时要求这样做-S@mclayton我已经这样做了。我尝试用一个新的Visual Studio解决方案(C#类库,.Net Framework 4.7.2)重新解决这个问题,添加NuGet包
Microsoft.PowerShell.5.1.ReferenceAssembly
,然后将代码粘贴到两个新的类文件中(序列化格式除外-使用
Input.ToString()
新Guid(this.Input)
转换值)。然后,在PowerShell
导入模块中“\MyCmdlet.dll”;新Guid |转换GuidToRaw |转换RawToGuid