Làm thế nào bạn có thể kiểm tra nếu một đối tượng có một thuộc tính cụ thể?


93

Làm thế nào bạn có thể kiểm tra nếu một đối tượng có một thuộc tính cụ thể?

Đánh giá cao tôi có thể làm ...

$members = Get-Member -InputObject $myobject 

và sau đó foreachthông qua $members, nhưng có một chức năng để kiểm tra xem đối tượng có thuộc tính cụ thể hay không?

Thông tin bổ sung: Vấn đề là tôi đang nhập hai loại tệp CSV khác nhau, một loại có hai cột, loại còn lại có ba cột. Tôi không thể làm cho séc hoạt động với "Thuộc tính", chỉ với "NoteProperty" ... bất kể sự khác biệt là gì

if ( ($member.MemberType -eq "NoteProperty" ) -and ($member.Name -eq $propertyName) ) 

6
($object.property -ne $null)?
arco444

2
Có vấn đề gì không nếu propery tồn tại nhưng có một $nullgiá trị
Matt

1
@ arco444 nope - điều đó yêu cầu thuộc tính tồn tại để nó thành công. - Nếu bạn có dữ liệu động (tức là từ một yêu cầu web) trong đó một số hàng thậm chí không chỉ định thuộc tính đó, việc kiểm tra đó sẽ không thành công. :(
BrainSlugs83

Câu trả lời:


103

Như thế này?

 [bool]($myObject.PSobject.Properties.name -match "myPropertyNameToTest")

16
Câu trả lời này chỉ hoạt động đối với powerShell v3 trở lên. Phần sau sẽ hoạt động ngay cả với powerShell v2 trở lên: [bool] ($ file.psobject.Properties | where {$ _. Name -eq "myPropertyNameToTest"})
Patrick

33
$myObject.PSobject.Properties.Name -contains "myPropertyNameToTest"tốt hơn. Không cần phải lo lắng về khả năng khớp mẫu và sau đó, bạn cũng sẽ không cần truyền tới Boolean.
Bacon Bits

2
Điều gì sẽ xảy ra nếu đối tượng có thuộc tính ThisisMyPropertyvà bạn muốn kiểm tra MyProperty? Tất cả các giải pháp trong câu trả lời này sẽ dẫn đến dương tính giả.
Zoltán Tamási

3
@KolobCanyon Điều đó sẽ không hoạt động trong Chế độ nghiêm ngặt.
user2864740

1
Mã này sẽ cho kết quả dương tính giả nếu ví dụ như bạn đang kiểm tra "Đếm" và đối tượng có thuộc tính gọi là "ThingCount".
dan-gph

71

Bạn có thể dùng Get-Member

if(Get-Member -inputobject $var -name "Property" -Membertype Properties){
#Property exists
}

12
Câu trả lời hay nhất IMHO. Điều này hoạt động với các đối tượng .NET không có thành viên PSobject. Chúng ta cũng có thể loại bỏ tùy chọn -Membertype nếu chúng ta không quan tâm đối tượng chứa loại thành viên nào - chỉ tên thành viên. Rất hữu ích với các đối tượng Invoke-RestMethod hoặc ConvertFrom-Json!
Mister_Tom

2
Cú pháp ngắn mà không kiểm tra loại: if($var | Get-Member Property){ }, thậm chí ngắn hơn nhưng ít có thể đọc:if($var | gm Property){ }
zett42

Theo tôi đây là câu trả lời tốt nhất.
Kiran Hegde

25

Điều này ngắn gọn và dễ đọc:

"MyProperty" -in $MyObject.PSobject.Properties.Name

Chúng ta có thể đặt nó trong một hàm:

function HasProperty($object, $propertyName)
{
    $propertyName -in $object.PSobject.Properties.Name
}

Tôi thích câu trả lời này, nhưng nó dường như không hoạt động trong một số trường hợp câu trả lời của CB.
edwin

Hoặc, trong đó "succinct" = "rác không cần thiết được giới thiệu qua Chế độ nghiêm ngặt mà không có trường hợp sử dụng dự phòng tốt" (tức là không ?.tương đương): | Điều này cũng sẽ không thành công đối với một số biến thể của $MyObject, đặc biệt là $ null. Đó không phải là trường hợp của chuỗi null bên ngoài Chế độ nghiêm ngặt.
user2864740

5

Tôi đã sử dụng phần sau để trả về giá trị thuộc tính, vì nó sẽ được truy cập thông qua$thing.$prop , nếu "thuộc tính" sẽ tồn tại và không ném ra một ngoại lệ ngẫu nhiên. Nếu thuộc tính "không tồn tại" (hoặc có giá trị null) thì $nullđược trả về: phương pháp này hoạt động trong / hữu ích cho chế độ nghiêm ngặt , bởi vì, sẽ bắt được tất cả.

Tôi thấy cách tiếp cận này hữu ích vì nó cho phép Đối tượng tùy chỉnh PS, đối tượng .NET bình thường, PS HashTables và bộ sưu tập .NET như Từ điển được coi là "tương đương kiểu vịt" , mà tôi thấy là khá phù hợp với PowerShell.

Tất nhiên, điều này không đáp ứng định nghĩa chặt chẽ của "có một thuộc tính" .. mà câu hỏi này có thể được giới hạn rõ ràng. Nếu chấp nhận định nghĩa lớn hơn của "property" được giả định ở đây, phương thức có thể được sửa đổi nhỏ để trả về boolean.

Function Get-PropOrNull {
    param($thing, [string]$prop)
    Try {
        $thing.$prop
    } Catch {
    }
}

Ví dụ:

Get-PropOrNull (Get-Date) "Date"                   # => Monday, February 05, 2018 12:00:00 AM
Get-PropOrNull (Get-Date) "flub"                   # => $null
Get-PropOrNull (@{x="HashTable"}) "x"              # => "HashTable"
Get-PropOrNull ([PSCustomObject]@{x="Custom"}) "x" # => "Custom"
$oldDict = New-Object "System.Collections.HashTable"
$oldDict["x"] = "OldDict"
Get-PropOrNull $d "x"                              # => "OldDict"

Và, hành vi này có thể không [luôn] được mong muốn .. tức là. không thể phân biệt giữa x.Countx["Count"].


3

Đối với tôi MyProperty" -in $MyObject.PSobject.Properties.Namekhông có tác dụng, tuy nhiên

$MyObject.PSobject.Properties.Name.Contains("MyProperty")

làm


2

Nếu bạn đang sử dụng Chế độ nghiêm ngặt và psobject có thể trống, nó sẽ báo lỗi cho bạn.

Đối với tất cả các mục đích, điều này sẽ làm:

    if (($json.PSobject.Properties | Foreach {$_.Name}) -contains $variable)

1

Thực tương tự như kiểm tra javascript:

foreach($member in $members)
{
    if($member.PropertyName)
    {
        Write $member.PropertyName
    }
    else
    {
        Write "Nope!"
    }
}

1
Điều này có thể không hoạt động nếu thuộc tính thực sự có giá trị $ null.
Tola Odejayi

8
Điều này sẽ không thành công nếu PowerShell ở chế độ nghiêm ngặt.
Ian Kemp

@IanKemp Chế độ nghiêm ngặt là gì? Thích Chính sách Thực thi?
Kolob Canyon

1
@KolobCanyon docs.microsoft.com/en-za/powershell/module/… - về cơ bản nó là PS tương đương với JavaScript use strict.
Ian Kemp

1
Điều này cũng sẽ không hoạt động nếu thuộc tính tồn tại và được đặt thành $ false.

1

Chỉ để làm rõ đối tượng sau

$Object

Với các thuộc tính sau

type        : message
user        : john.doe@company.com
text        : 
ts          : 11/21/2016 8:59:30 PM

Những điều sau đây là sự thật

$Object.text -eq $NULL
$Object.NotPresent -eq $NULL

-not $Object.text
-not $Object.NotPresent

Vì vậy, các câu trả lời trước đó kiểm tra rõ ràng thuộc tính theo tên là cách chính xác nhất để xác minh rằng thuộc tính đó không có mặt.


1

Chỉ cần kiểm tra với null.

($myObject.MyProperty -ne $null)

Nếu bạn chưa đặt PowerShell thành Chế độ nghiêm ngặt , điều này sẽ hoạt động ngay cả khi thuộc tính không tồn tại:

$obj = New-Object PSObject;                                                   
Add-Member -InputObject $obj -MemberType NoteProperty -Name Foo -Value "Bar";
$obj.Foo; # Bar                                                                  
($obj.MyProperty -ne $null);  # False, no exception

2
Theo như tôi thấy, điều này hoạt động nếu thuộc tính tồn tại và là $ null, nhưng không hoạt động nếu thuộc tính không tồn tại - cố gắng truy cập vào nó để thực hiện kiểm tra null sẽ ném ra một ngoại lệ.
Peter

@Peter Bạn có thể cung cấp một ví dụ về kiểm tra null ném một ngoại lệ khi thuộc tính không tồn tại. Tôi đã thêm một ví dụ trong đó một thuộc tính không tồn tại và không có ngoại lệ.
Shaun Luttin

2
Chạy cái này: Set-Strictmode -version Latest;$obj = ConvertFrom-Json -InputObject '{"name":"test", "version":"1.1.0"}';If($obj.StartDate -ne $null){Write-Verbose -Message $obj.startDate -Verbose}và bạn sẽ gặp lỗi Không thể tìm thấy Thuộc tính 'Ngày bắt đầu' trên đối tượng này. Tuy nhiên, tôi cần đủ điều kiện nhận xét của mình - bạn sẽ không hiểu nếu Chế độ nghiêm ngặt không được đặt. Tôi luôn đặt nó, vì vậy không bao giờ nhận ra cho đến khi tôi thử nghiệm điều này! Tuy nhiên, tôi nghĩ rằng hầu hết mọi người sử dụng (hoặc nên sử dụng) 'Chế độ cài đặt nghiêm ngặt'.
Peter

2
Có lẽ là tốt nhất nếu bạn đủ điều kiện cho câu trả lời của mình và tôi sẽ xóa phiếu phản đối của mình? Mọi người đều đã học được điều gì đó, đó là điểm mấu chốt :-)
Peter

0

Tôi đã kết thúc với chức năng sau ...

function HasNoteProperty(
    [object]$testObject,
    [string]$propertyName
)
{
    $members = Get-Member -InputObject $testObject 
    if ($members -ne $null -and $members.count -gt 0) 
    { 
        foreach($member in $members) 
        { 
            if ( ($member.MemberType -eq "NoteProperty" )  -and `
                 ($member.Name       -eq $propertyName) ) 
            { 
                return $true 
            } 
        } 
        return $false 
    } 
    else 
    { 
        return $false; 
    }
}

0

Gần đây tôi đã chuyển sang đặt chế độ nghiêm ngặt -version 2.0 và các thử nghiệm rỗng của tôi không thành công.

Tôi đã thêm một chức năng:

#use in strict mode to validate property exists before using
function exists {
  param($obj,$prop)
  try {
    if ($null -ne $obj[$prop]) {return $true}
    return $false
  } catch {
    return $false
  }
  return $false
}

Bây giờ tôi viết mã

if (exists $run main) { ...

hơn là

if ($run.main -ne $null) { ...

và chúng tôi đang trên con đường của mình. Có vẻ hoạt động trên các đối tượng và bảng băm

Như một lợi ích ngoài ý muốn, đó là việc gõ ít hơn.


Đối với null hoặc trống, tôi luôn sử dụng: IF ([string] :: IsNullOrEmpty ($ userID)) {write-host "Null or

0

Tôi chỉ muốn thêm vào cuộc thảo luận, bởi vì tôi vừa dành hàng giờ để gỡ lỗi một mã hoạt động ở một nơi khác.

Trả lời của CB. hoạt động tốt để so khớp biến với tên của thuộc tính (dưới dạng chuỗi). Sự cố bắt đầu xảy ra khi biến khớp với một phần của tên thuộc tính.

if([bool]($allFiles.PSobject.Properties.name -match $_.Name) -ne $true){

Sau đó, tôi sử dụng nó để tham chiếu đến thuộc tính của một đối tượng, nhưng vì nó chỉ khớp với một phần của thuộc tính khác nên thuộc tính thực tế có tên chính xác đó không tồn tại, nên hoạt động trả về giá trị 'null'.

Chỉ sau này, tôi đã sử dụng giải pháp do dan-gph đề xuất , rất gọn gàng:

if([bool]($_.Name -in $allFiles.PSobject.Properties.Name) -ne $true){

Điều này đảm bảo rằng hai giá trị là giống hệt nhau . Tôi biết phải tìm ở đâu nhưng vẫn rất đau đớn khi phát hiện ra rằng vấn đề là một số chuỗi tên khớp với 2 ký tự. tiền tố nhưng nếu không thì giống nhau.


-1

Tôi vừa mới bắt đầu sử dụng PowerShell với PowerShell Core 6.0 (beta) và các thao tác sau chỉ hoạt động:

if ($members.NoteProperty) {
   # NoteProperty exist
}

hoặc là

if (-not $members.NoteProperty) {
   # NoteProperty does not exist
}

1
Không phải với StrictMode trên
Casper Leon Nielsen

-1

Bạn có thể kiểm tra bằng:

($Member.PropertyNames -contains "Name") điều này sẽ kiểm tra thuộc tính Được đặt tên


-1

Để xác định đối tượng nào trong mảng có thuộc tính

$HasProperty = $ArrayOfObjects | Where-Object {$_.MyProperty}

Không thành công trong Chế độ nghiêm ngặt khi thuộc tính không tồn tại.
user2864740 11/09/19
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.