我写了一些小测试代码:
namespace Test {
using System;
using System.Management.Automation;
using System.Linq;
using System.IO;
[Cmdlet(VerbsCommon.Get, "Test", DefaultParameterSetName="Path")]
public sealed class GetTestCommand : PSCmdlet {
private String[] _paths;
private Boolean _wildcards;
[Parameter(
ParameterSetName="Path",
Mandatory=true,
Position=0,
ValueFromPipeline=true,
ValueFromPipelineByPropertyName=true
)]
public String[] Path {
get { return _paths; }
set {
_wildcards = true;
_paths = value;
}
}
[Parameter(
ParameterSetName="LiteralPath",
Mandatory=true,
Position=0,
ValueFromPipeline=false,
ValueFromPipelineByPropertyName=true
)]
public String[] LiteralPath {
get { return _paths; }
set { _paths = value; }
}
protected override void ProcessRecord() {
ProviderInfo pi;
(from p in _paths
select new {
FilePath = (_wildcards ?
this.SessionState.Path.GetResolvedProviderPathFromPSPath(p, out pi)[0] :
this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(p))
}).ToList()
.ForEach(i => WriteObject(i.FilePath));
}
}
}
这有效:
Get-Test *.txt
这有效:
Get-ChildItem -Filter *.txt | Get-Test
但这不起作用:
Get-ChildItem -Filter *.txt -Recurse | Get-Test
请解释我的错误,如何解决以及我应该阅读什么来深入理解PowerShell的机制。
答案 0 :(得分:0)
问题是您实际上没有处理从Powershell cmdlet
收到的对象。
正确的方法是将接收参数绑定到适当类型的对象,然后访问其属性,即:
[Cmdlet(VerbsCommon.Get, "Test", DefaultParameterSetName = "Path")]
public sealed class GetTestCommand : PSCmdlet
{
private FileSystemInfo[] _paths;
[Parameter(
ParameterSetName = "Path",
Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true
)]
public FileSystemInfo[] Path
{
get { return _paths; }
set
{
_paths = value;
}
}
protected override void ProcessRecord()
{
ProviderInfo pi;
(from p in _paths
where (p.GetType() != typeof(DirectoryInfo))
select new
{
FilePath = p.FullName}).ToList()
.ForEach(i => WriteObject(i.FilePath));
}
}
为了将来参考,您可能需要检查cmdlet
与Get-ChildItem | foreach-object -process { $_.GetType() }
收到的类型。
而且,您可以使用Powershell
以相同的方式实现您想要的目标,例如:Get-ChildItem | foreach-object -process { $_.FullName }
。
要获得与纯Powershell
完全相同的结果,请尝试:
Get-ChildItem -Recurse | ForEach-Object -Process { if ($_ -isnot [System.IO.DirectoryInfo]) { Write-Host $_.FullName } }