Powershell'de nesne özelliklerini yazdırma


121

Etkileşimli konsolda çalışırken, yeni bir nesne tanımlarsam ve ona aşağıdaki gibi bazı özellik değerleri atarsam:

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

Sonra değişkenimin adını etkileşimli pencereye yazdığımda Powershell, nesne özelliklerinin ve değerlerinin bir özetini verir:

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

Temelde sadece bunu yapmak istiyorum ama bir komut dosyasındaki bir işlevin içinden. İşlev bir nesne oluşturur ve bazı özellik değerlerini ayarlar ve geri dönmeden önce Powershell penceresine nesne değerlerinin bir özetini yazdırmasını istiyorum. İşlev içinde Write-Host'u kullanmayı denedim:

Write-Host $obj

Ancak bu, özet değil, yalnızca nesnenin türünü verir:

System.Object

Fonksiyonumun Powershell penceresine nesnenin özellik değerlerinin bir özetini çıkarmasını nasıl sağlayabilirim?

Yanıtlar:


188

Bunu dene:

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

veya

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

4
-ForceÇalışması için parametreyi Write-Host ($obj | Format-List -Force | Out-String)
iletmem

1
Ihh! Hala ekranda yatay olarak görüntülenir .... herhangi bir çıktı arabelleğinizin dışına çıkarsa koyar .... POSH ile aşktan nefret ediyorum
Kolob Canyon

Kullanarak $objs = @();ve $objs = $objs + $obj; kullanabilirim ConvertTo-Html: $ cols = $ objs | ConvertTo-Html -Fragment -Property Name, DataType, Default, Identity, InPrimaryKey, IsForeignKey, Description;
Kiquenet

33

Bu soruna çözümüm $ () alt ifade bloğunu kullanmaktı .

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"

verir:

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

16

Powershell'de nesnenin özelliklerini ve değerlerini yazdırmak için. Aşağıdaki örnekler benim için iyi çalışıyor.

$ pool = Get-Item "IIS: \ AppPools.NET v4.5"

$ havuz | Get-Üye

   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()
...

$ havuz | Seç-Nesne -Özellik * # -Özelliği atlayabilirsiniz

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
Bunun son varyantı benim için en iyi çalıştı - hatta kısaltabilir $x | select *, interaktif için harika.
2018

Senaryoya koymak istersen bunun işe yarayacağını sanmıyorum. Eğer öyleyse, gerçekten konsola yazdırmak için belirtilenlere ek bir şey yapmanız gerektiğini düşünüyorum (yani: Write-Output <something-
Fractal

11

1. İpucu

Hiçbir zaman Write-Host'u kullanmayın.

12. İpucu

Bir PowerShell cmdlet'inden veya işlevinden bilgi vermenin doğru yolu, verilerinizi içeren bir nesne oluşturmak ve ardından bu nesneyi Yazma Çıktısı kullanarak işlem hattına yazmaktır.

-Don Jones: PowerShell Master

İdeal olarak, betiğiniz nesnelerinizi ( $obj = New-Object -TypeName psobject -Property @{'SomeProperty'='Test'}) oluşturur ve ardından bir Write-Output $objects. Çıkışı için boru yapardınız Format-Table.

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

PowerShell PowerObjectandPipingShell'i gerçekten çağırmalılar.


4
Teşekkürler Bob, mjolinor'un yanıtını, soruyu daha doğrudan yanıtladığını hissettiğim için kabul ettim, ancak sağladığınız bağlantılardan çok şey öğrendim ve çoğu durumda Write-Host'un uygun olmadığını kabul ettim. Teşekkürler!
John

1
Aynı teknik işe yarayacak ve muhtemelen Yazma-Verbose veya Yazma-Hata Ayıklama ile kullanılması daha uygun olacaktır.
mjolinor

4
Biliyorum, yıllarca geciktim ama Never use Write-Host.ifadeye katılmıyorum . Veri döndüren işlevler içinde Yazma Çıkışı kullanamazsınız çünkü bu işlevi "kirletecektir". Basit bir örnek. Hangi ReturnText işlevinin çıktı vereceğini tahmin edin? Bu yüzden her zaman Write-host içindeki fonksiyonları kullanıyorum. function ReturnText () {Yazma-Çıktısı "Bazı rastgele mesajlar" return "Geri dönmek istediğim şey"}
Denis Molodtsov

3
@DenisMolodtsov Tamamen katılıyorum. Bilgilerin günlüğe kaydedilmesi amacıyla Yazma Çıkışı, İşlev önemsiz olmadığı sürece ASLA kullanılmamalıdır. Birden fazla işlev seviyesi olduğunda ve çıktıyı döndürmeniz gerektiğinde başka bir şey kullanmanız GEREKİR ve Write-Host faturayı karşılar.
RobG

2
Ayrıca Write-Host, ilerlemeyi görmenize olanak tanıyan uzak bir oturumdan hemen geri yönlendirilir ve uzak bir oturum bir hata verirse Yazma-Çıktı bilgisi kaybolur.
RobG

3

Bazı genel notlar.


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

İkincisi, tüm dahili olmayan, derleyici tarafından oluşturulmayan özellikleri gösterecektir . İlki değil (her zaman) göstermek için görünür tüm Mülkiyet tipleri (benim testlerde, gösterilme görünmüyor CodeProperty MemberTypesürekli olsa - burada hiçbir garanti).


Get-Member için dikkat edilmesi gereken bazı anahtarlar

  • Get-Memberyok değil varsayılan olarak statik üye olsun. Ayrıca onları statik olmayan üyelerle birlikte (doğrudan) alamazsınız . Diğer bir deyişle, anahtarı kullanmak yalnızca statik üyelerin döndürülmesine neden olur:

    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)
    ...
  • Kullanın -Force.

    Get-MemberKomut kullanan kuvvet göstergesine nesnelerin iç üyeleri ve derleyici tarafından oluşturulan üye ekleme parametre. Get-Memberbu üyeleri alır, ancak varsayılan olarak onları gizler.

    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-JsonDerinlik ve okunabilir "serileştirme" için kullanın

Ben do not gerekli JSON kullanarak nesnelerin tasarrufu tavsiye (kullanımExport-Clixml yerine). Bununla birlikte, ConvertTo-Jsonderinliği belirlemenize de olanak tanıyan, aşağı yukarı okunabilir bir çıktı elde edebilirsiniz.

Belirtmemenin Depthima ettiğine dikkat edin-Depth 2

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

Ve okumayı planlamıyorsanız, okuyabilirsiniz -Compress(yani boşlukları soyun)

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

kullanım -InputObject eğer yapabilirsen (ve istekli)

PowerShell'i kullanırken% 99,9 oranında: performans önemli olmayacak veya performans sizin için önemli değil. Bununla birlikte , ihtiyacınız olmadığında borudan kaçınmanın bir miktar ek yük tasarrufu sağlayabileceği ve biraz hız ekleyebileceği unutulmamalıdır (genel olarak boru sistemi süper verimli değildir).

Yani, sahip olduğunuz her şey $objyazdırmak için kullanışlı bir tek şeyse (ve bazen benim gibi yazmak için çok tembel değilsiniz -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

Uyarı Get-Member -InputObject: $ obj bir koleksiyonsa (örneğin System.Object[]), koleksiyon nesnesinin kendisi hakkında bilgi alırsınız:

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

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

Koleksiyondaki Get-Memberher biri için isterseniz TypeName( her nesne için değil , her nesne için değil - hepsi aynı olan N nesneden oluşan bir koleksiyon TypeName, bunun için TypeNameyalnızca 1 tablo yazdırır TypeName, her nesne için N tablo değil) ...... doğrudan boru ile yapıştırın.


1

Aşağıdakiler benim için gerçekten iyi çalıştı. Yukarıdaki tüm cevapları bir araya getirdim, ayrıca aşağıdaki bağlantıda nesne özelliklerini görüntülemeyi okudum ve baskı nesneleri hakkında aşağıdaki kısa okumayı buldum.

aşağıdaki metni print_object.ps1 adlı bir dosyaya ekleyin:

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

powershell komut istemini açın, bu dosyanın bulunduğu dizine gidin ve aşağıdakileri yazın:

powershell -ExecutionPolicy ByPass -File is_port_in_use.ps1 -Elevated

Yazdırmak istediğiniz nesneyi 'System.DateTime' ile değiştirin. Nesne boşsa, hiçbir şey yazdırılmaz.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.