在Powershell中打印对象属性


119

在交互式控制台中工作时,如果我定义一个新对象并为其分配一些属性值,如下所示:

$obj = New-Object System.String
$obj | Add-Member NoteProperty SomeProperty "Test"

然后,当我在交互式窗口中输入变量的名称时,Powershell为我提供了对象属性和值的摘要:

PS C:\demo> $obj
SomeProperty                                                                                                                                                                                  
------------                                                                                                                                                                                  
Test

我基本上只是想这样做,但是要从脚本中的函数中进行。该函数创建一个对象并设置一些属性值,我希望它在返回之前将对象值的摘要打印到Powershell窗口中。我尝试在函数内使用Write-Host:

Write-Host $obj

但这只是输出对象的类型而不是摘要:

System.Object

如何让函数将对象的属性值摘要输出到Powershell窗口?

Answers:


186

试试这个:

Write-Host ($obj | Format-Table | Out-String)

要么

Write-Host ($obj | Format-List | Out-String)

4
我必须传递-Force参数才能使其正常工作,例如Write-Host ($obj | Format-List -Force | Out-String)
Bart Verkoeijen 2015年

1
啊! 它仍然水平显示在屏幕上...。我有一个爱与恨POSH
科罗布峡谷

使用$objs = @();$objs = $objs + $obj; 我可以使用ConvertTo-Html$的cols = $ OBJ文件| ConvertTo-Html -Fragment-属性名称,数据类型,默认值,标识,InPrimaryKey,IsForeignKey,描述;
Kiquenet '18年

32

我对这个问题的解决方案是使用$()子表达式块

Add-Type -Language CSharp @"
public class Thing{
    public string Name;
}
"@;

$x = New-Object Thing

$x.Name = "Bill"

Write-Output "My name is $($x.Name)"
Write-Output "This won't work right: $x.Name"

给出:

My name is Bill
This won't work right: Thing.Name

16

在Powershell中打印对象的属性和值。以下示例对我来说效果很好。

$ pool =获取项目“ IIS:\ AppPools.NET v4.5”

$ pool | 获得会员

   TypeName: Microsoft.IIs.PowerShell.Framework.ConfigurationElement#system.applicationHost/applicationPools#add

Name                        MemberType            Definition
----                        ----------            ----------
Recycle                     CodeMethod            void Recycle()
Start                       CodeMethod            void Start()
Stop                        CodeMethod            void Stop()
applicationPoolSid          CodeProperty          Microsoft.IIs.PowerShell.Framework.CodeProperty
state                       CodeProperty          Microsoft.IIs.PowerShell.Framework.CodeProperty
ClearLocalData              Method                void ClearLocalData()
Copy                        Method                void Copy(Microsoft.IIs.PowerShell.Framework.ConfigurationElement ...
Delete                      Method                void Delete()
...

$ pool | Select-Object -Property *#您可以省略-Property

name                        : .NET v4.5
queueLength                 : 1000
autoStart                   : True
enable32BitAppOnWin64       : False
managedRuntimeVersion       : v4.0
managedRuntimeLoader        : webengine4.dll
enableConfigurationOverride : True
managedPipelineMode         : Integrated
CLRConfigFile               :
passAnonymousToken          : True
startMode                   : OnDemand
state                       : Started
applicationPoolSid          : S-1-5-82-271721585-897601226-2024613209-625570482-296978595
processModel                : Microsoft.IIs.PowerShell.Framework.ConfigurationElement
...

1
此方法的最后一个变体最适合我-甚至可以将其缩短为$x | select *,非常适合进行交互。
加倍

我想将其放入脚本中不起作用。如果是这样,我认为您必须做一些声明以外的事情才能将其实际打印到控制台(即:Write-Output <something-something>)
Fractal

11

提示1

切勿使用Write-Host。

提示#12

从PowerShell cmdlet或函数输出信息的正确方法是创建一个包含您的数据的对象,然后使用Write-Output将对象写入管道。

-Don Jones:PowerShell Master

理想情况下,脚本将创建对象($obj = New-Object -TypeName psobject -Property @{'SomeProperty'='Test'}),然后执行一个Write-Output $objects。您将通过管道将输出传输到Format-Table

PS C:\> Run-MyScript.ps1 | Format-Table

他们应该真正调用PowerShell PowerObjectandPipingShell。


4
谢谢Bob,我接受了mjolinor的回答,因为我认为它可以更直接地回答问题,但是我从您提供的链接中学到了很多,并同意在大多数情况下Write-Host不适用。谢谢!
约翰,

1
相同的技术将起作用,并且可能更适合与Write-Verbose或Write-Debug一起使用。
mjolinor 2013年

4
我知道,我迟到了很多年,但是我不同意Never use Write-Host.声明。您不能在返回数据的函数内部使用Write-Output,因为它将“污染”该函数。简单的例子。猜猜将输出什么ReturnText函数?这就是为什么我总是在函数内部使用Write-host的原因。函数ReturnText(){Write-Output“一些随机消息”返回“我要返回的内容”}
Denis Molodtsov

3
@DenisMolodtsov我完全同意。为了记录信息,除非函数不重要,否则切勿使用Write-Output。一旦存在多个功能级别,并且您需要返回输出,则必须使用其他功能,并且Write-Host符合要求。
RobG

2
Write-Host也将立即从远程会话中导回,从而使您可以查看进度,如果远程会话抛出错误,Write-Output信息将丢失。
RobG

3

一些一般说明。


$obj | Select-Object $obj | Select-Object -Property *

后者将显示所有非内部的,非编译器生成的属性。前者似乎并没有(总是)显示所有的 Property类型(在我的测试中,它的确显示出了CodeProperty MemberType一致的状态-此处没有保证)。


Get-Member需要注意的一些开关

  • Get-Member没有在默认情况下得到的静态成员。您也不能(直接)使它们非静态成员在一起。也就是说,使用开关将仅返回静态成员:

    PS Y:\Power> $obj | Get-Member -Static
    
       TypeName: System.IsFire.TurnUpProtocol
    
    Name        MemberType Definition
    ----        ---------- ----------
    Equals      Method     static bool Equals(System.Object objA, System.Object objB)
    ...
  • 使用-Force

    Get-Member命令使用Force参数将对象的固有成员和编译器生成的成员添加到显示中。Get-Member获取这些成员,但默认情况下将其隐藏。

    PS Y:\Power> $obj | Get-Member -Static
    
       TypeName: System.IsFire.TurnUpProtocol
    
    Name          MemberType     Definition
    ----          ----------     ----------
    ...
    pstypenames   CodeProperty   System.Collections.ObjectModel.Collection...
    psadapted     MemberSet      psadapted {AccessRightType, AccessRuleType,...
    ...

使用ConvertTo-Json深度和可读性“系列化”

没有必要建议使用JSON保存对象(Export-Clixml改为使用)。但是,您可以从中获得或多或少可读的输出ConvertTo-Json,这也允许您指定深度。

请注意,未指定Depth暗示-Depth 2

PS Y:\Power> ConvertTo-Json $obj -Depth 1
{
    "AllowSystemOverload":  true,
    "AllowLifeToGetInTheWay":  false,
    "CantAnyMore": true,
    "LastResortOnly": true,
...

而且,如果您不打算阅读,也可以-Compress(例如,带空格)

PS Y:\Power> ConvertTo-Json $obj -Depth 420 -Compress

-InputObject如果可以(并愿意)使用,请使用

使用PowerShell的99.9%的时间:性能无关紧要,或者您不在乎性能。但是,应注意的是,在不需要管道时避免使用管道可以节省一些开销并增加一些速度(通常,管道不是超级有效的)。

就是说,如果您拥有的全部都可以$obj方便地进行打印(并且有时不会像我这样懒惰地输入-InputObject):

# select is aliased (hardcoded) to Select-Object
PS Y:\Power> select -Property * -InputObject $obj
# gm is aliased (hardcoded) to Get-Member
PS Y:\Power> gm -Force -InputObject $obj

警告Get-Member -InputObject 如果$ obj是一个集合(例如System.Object[]),您最终将获得有关集合对象本身的信息:

PS Y:\Power> gm -InputObject $obj,$obj2
   TypeName: System.Object[]

Name        MemberType            Definition
----        ----------            ----------
Count       AliasProperty         Count = Length
...

如果你想Get-Member为每个TypeName集合中(NB每个TypeName不是每个对象- N的集合与所有相同的对象TypeName将只打印1代表为TypeName,不为N表为每个对象)......只需坚持用管道将其直接插入即可。


1

下面对我来说真的很好。我将以上所有答案拼凑在一起,并在以下链接中了解了有关显示对象属性的内容,并提出了以下 有关打印对象的简短内容

将以下文本添加到名为print_object.ps1的文件中:

$date = New-Object System.DateTime
Write-Output $date | Get-Member
Write-Output $date | Select-Object -Property *

打开powershell命令提示符,转到该文件所在的目录,然后键入以下内容:

powershell -ExecutionPolicy ByPass -File is_port_in_use.ps1 -Elevated

只需将“ System.DateTime”替换为您要打印的任何对象。如果对象为null,则不会打印任何内容。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.