在Powershell中打印对象属性

时间:2013-04-03 16:17:31

标签: powershell

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

$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窗口?

7 个答案:

答案 0 :(得分:142)

试试这个:

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

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

答案 1 :(得分:21)

我对此问题的解决方案是使用$() sub-expression block

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

答案 2 :(得分:13)

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

$ pool = Get-Item" 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
...

答案 3 :(得分:10)

<强> Tip #1

  

永远不要使用Write-Host。

<强> Tip #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 :(得分:1)

# Json to object
$obj = $obj | ConvertFrom-Json
Write-host $obj.PropertyName

答案 5 :(得分:0)

以下内容对我确实非常有用。我将以上所有答案汇总在一起,并阅读了以下链接中有关显示对象属性的内容,并提出了以下内容 short read about printing objects

将以下文本添加到名为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,则不会打印任何内容。

答案 6 :(得分:0)

一些常规说明。


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

后者将显示 all 个非内部,非编译器生成的属性。前者的 not 不会(总是)显示 all 属性类型(在我的测试中,它的确确实显示了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(每个TypeName的NB,每个对象的 not -一组具有相同TypeName的N个对象的集合将只为该TypeName打印1个表,而不为每个对象打印N个表)……只需直接用管道将其插入即可。