如何测试对象是否具有特定属性?

时间:2014-11-18 15:08:17

标签: powershell powershell-v3.0

如何测试对象是否具有特定属性?

欣赏我能做到......

$members = Get-Member -InputObject $myobject 

然后foreach通过$members,但是有一个函数可以测试对象是否具有特定属性吗?

其他信息: 问题是我正在导入两种不同类型的CSV文件,一种是两列,另一种是三列。我无法使用“Property”进行检查,仅使用“NoteProperty”... 无论差异是什么

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

17 个答案:

答案 0 :(得分:72)

喜欢这个吗?

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

答案 1 :(得分:46)

您可以使用Get-Member

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

答案 2 :(得分:12)

这是简洁易读的:

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

我们可以把它放在一个函数中:

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

答案 3 :(得分:3)

我一直在使用以下返回属性值,因为它将通过$thing.$prop 访问,如果“属性”将存在而不会抛出随机异常。如果属性“不存在”(或具有空值),则返回$null:此方法在严格模式中起作用,因为,好吧,Gonna Catch'他们全部。

我发现这种方法很有用,因为它允许PS自定义对象,普通的.NET对象,PS HashTables和像.NET这样的.NET集合被视为“鸭型等效”,我发现适合PowerShell。

当然,这不符合“有一个属性”的严格定义..这个问题可能明确限于此。如果接受这里假定的“属性”的更大定义,则可以通过简单地修改该方法来返回布尔值。

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

示例:

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"

并且,这种行为可能不会[总是]需要..即。无法区分x.Countx["Count"]

答案 4 :(得分:2)

如果您使用的是StrictMode且psobject可能为空,则会出错。

出于所有目的,这将做:

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

答案 5 :(得分:2)

真实类似于javascript检查:

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

答案 6 :(得分:1)

只需检查null即可。

($myObject.MyProperty -ne $null)

如果您没有set PowerShell to StrictMode,即使该属性不存在,此功能仍然有效:

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

答案 7 :(得分:1)

只是澄清一下 给出以下对象

x

具有以下属性

$Object

以下是真的

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

因此,通过名称显式检查属性的早期答案是验证该属性不存在的最正确方法。

答案 8 :(得分:1)

试试这个对于严格安全的单衬。

[bool]$myobject.PSObject.Properties[$propertyName]

例如:

Set-StrictMode -Version latest;
$propertyName = 'Property1';
$myobject = [PSCustomObject]@{ Property0 = 'Value0' };

if ([bool]$myobject.PSObject.Properties[$propertyName]) {
    $value = $myobject.$propertyName;
}

答案 9 :(得分:0)

我刚刚开始在PowerShell Core 6.0(测试版)中使用PowerShell,之后只需使用:

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

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

答案 10 :(得分:0)

我最终得到了以下功能......

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; 
    }
}

答案 11 :(得分:0)

我最近切换到设置严格模式-version 2.0,并且我的null测试失败。

我添加了一个功能:

#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
}

现在我编码

if (exists $run main) { ...

而不是

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

,我们正在前进。似乎可以处理对象和哈希表

作为一项意料不到的好处,它减少了打字。

答案 12 :(得分:0)

用于识别数组中的哪些对象具有属性

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

答案 13 :(得分:0)

对我来说,$ MyObject.PSobject.Properties.Name中的“ MyProperty”无效,但是$ MyObject.PSobject.Properties.Name.Contains(“ MyProperty”)有效

答案 14 :(得分:0)

对我来说这项工作

"""
This example shows how to create an international shipment and generate a waybill as output.
The example takes outset in a real practical use case, where electronic trade documents are
used and an existing PDF commercial invoice is added along with product descriptions via ETD.
Further, it adds event notifications to allow for emails to be sent to the end recipient.
The script is comprised of a FedExLabelHelper class with all core functions, and a use case
example with minimal dummy data
"""
from example_config import CONFIG_OBJ
from pathlib import Path
import binascii
import datetime
from fedex.services.ship_service import FedexProcessShipmentRequest

# ----------------------------------------------------
# FedEx class for creating shipments
class FedexLabelHelper:
    mCommodities = []

    def __init__(self):
        pass

    # ----------------------------------------------------
    # set overall shipment configuration
    def setShipmentConfig(
        self,
        CONFIG_OBJ,
        invoice_info,
        cust_tran_id="*** ShipService Request v17 using Python ***",
        dropoffType="BUSINESS_SERVICE_CENTER",
        shippingPaymentType="SENDER",
        labelFormatType="COMMON2D",
        labelSpecificationImageType="PDF",
        labelSpecificationStockType="PAPER_7X4.75",
        labelPrintingOrientation="TOP_EDGE_OF_TEXT_FIRST",
        LabelOrder="SHIPPING_LABEL_FIRST",
    ):
        self.invoice_info = invoice_info
        self.dropoffType = dropoffType
        self.serviceType = "INTERNATIONAL_PRIORITY" if invoice_info["ShippingExpress"] == True else "INTERNATIONAL_ECONOMY"
        self.mCommodities.clear()
        self.CONFIG_OBJ = CONFIG_OBJ
        self.shipment = FedexProcessShipmentRequest(CONFIG_OBJ, customer_transaction_id=cust_tran_id)

        self.shipment.RequestedShipment.DropoffType = dropoffType
        self.shipment.RequestedShipment.ServiceType = self.serviceType
        self.shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = CONFIG_OBJ.account_number
        self.shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Address.CountryCode = "DK"
        self.shipment.RequestedShipment.ShippingChargesPayment.PaymentType = shippingPaymentType

        labelSpecification = self.shipment.create_wsdl_object_of_type("LabelSpecification")
        labelSpecification.LabelFormatType = labelFormatType
        labelSpecification.LabelStockType = labelSpecificationStockType
        labelSpecification.ImageType = labelSpecificationImageType
        labelSpecification.LabelOrder = LabelOrder
        labelSpecification.LabelPrintingOrientation = labelPrintingOrientation
        self.shipment.RequestedShipment.LabelSpecification = labelSpecification

    # ----------------------------------------------------
    # set sender information
    def setSenderInfo(self, sender):

        self.shipment.RequestedShipment.Shipper.Contact.PersonName = sender["Name"]
        self.shipment.RequestedShipment.Shipper.Contact.CompanyName = sender["Company"]
        self.shipment.RequestedShipment.Shipper.Contact.PhoneNumber = sender["Phone"]
        self.shipment.RequestedShipment.Shipper.Contact.EMailAddress = sender["Email"]
        self.shipment.RequestedShipment.Shipper.Address.StreetLines = sender["Address"]
        self.shipment.RequestedShipment.Shipper.Address.City = sender["City"]
        self.shipment.RequestedShipment.Shipper.Address.StateOrProvinceCode = sender["Region"]
        self.shipment.RequestedShipment.Shipper.Address.PostalCode = sender["Zip"]
        self.shipment.RequestedShipment.Shipper.Address.CountryCode = sender["CountryCode"]
        self.shipment.RequestedShipment.Shipper.Address.Residential = sender["Residential"]

        ti = self.shipment.create_wsdl_object_of_type("TaxpayerIdentification")
        ti.Number = sender["VAT"]
        ti.TinType = "BUSINESS_NATIONAL"
        self.shipment.RequestedShipment.Shipper.Tins = ti

    # ----------------------------------------------------
    # upload all documents (invoice and product information)
    def upload_all_documents(self):
        doc_ids = []
        doc_ids.append(self.upload_document(self.invoice_info["InvoicePath"], "COMMERCIAL_INVOICE"))

        for pdf in self.invoice_info["Pdfs"]:
            doc_ids.append(self.upload_document(pdf, "OTHER"))

        return doc_ids

    # ----------------------------------------------------
    # function for uploading documents as electronic trade documents and getting the response doc IDs
    def upload_document(self, path, type):
        from fedex.services.document_service import FedexDocumentServiceRequest

        # specify prefix for use in attachment naming
        if type == "COMMERCIAL_INVOICE":
            prefix = "invoice_"
        else:
            prefix = "product_description_"

        uploadRequest = FedexDocumentServiceRequest(self.CONFIG_OBJ)
        uploadRequest.OriginCountryCode = "DK"
        uploadRequest.DestinationCountryCode = self.shipment.RequestedShipment.Recipient.Address.CountryCode
        uploadRequest.Usage = "ELECTRONIC_TRADE_DOCUMENTS"

        clientdetails = uploadRequest.create_wsdl_object_of_type("ClientDetail")
        clientdetails.AccountNumber = self.CONFIG_OBJ.account_number
        clientdetails.MeterNumber = self.CONFIG_OBJ.meter_number
        uploadRequest.ClientDetail = clientdetails

        webAuthDetails = uploadRequest.create_wsdl_object_of_type("WebAuthenticationDetail")
        webAuthDetails.ParentCredential.Key = self.CONFIG_OBJ.key
        webAuthDetails.ParentCredential.Password = self.CONFIG_OBJ.password
        webAuthDetails.UserCredential.Key = self.CONFIG_OBJ.key
        webAuthDetails.UserCredential.Password = self.CONFIG_OBJ.password
        uploadRequest.WebAuthenticationDetail = webAuthDetails

        docdetails = uploadRequest.create_wsdl_object_of_type("UploadDocumentDetail")
        docdetails.LineNumber = 1
        docdetails.DocumentType = type
        docdetails.FileName = prefix + path
        fileContent = open(path, "rb").read()
        fileBase64 = binascii.b2a_base64(fileContent)
        docdetails.DocumentContent = fileBase64.decode("cp1250")
        uploadRequest.Documents = docdetails

        uploadRequest.send_request()

        doc_id = uploadRequest.response.DocumentStatuses[0].DocumentId

        return doc_id

    # ----------------------------------------------------
    # set recipient information
    def setRecipientInfo(self, recipient):
        self.shipment.RequestedShipment.Recipient.Contact.PersonName = recipient["Name"]
        self.shipment.RequestedShipment.Recipient.Contact.CompanyName = recipient["Company"]
        self.shipment.RequestedShipment.Recipient.Contact.PhoneNumber = recipient["Phone"]
        self.shipment.RequestedShipment.Recipient.Contact.EMailAddress = recipient["Email"]
        self.shipment.RequestedShipment.Recipient.Address.StreetLines = recipient["Address"]
        self.shipment.RequestedShipment.Recipient.Address.City = recipient["City"]
        self.shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = recipient["Region"]
        self.shipment.RequestedShipment.Recipient.Address.PostalCode = recipient["Zip"]
        self.shipment.RequestedShipment.Recipient.Address.CountryCode = recipient["CountryCode"]
        self.shipment.RequestedShipment.Recipient.Address.Residential = recipient["Residential"]

        ti = self.shipment.create_wsdl_object_of_type("TaxpayerIdentification")
        ti.Number = recipient["VAT"]
        ti.TinType = "BUSINESS_NATIONAL"
        self.shipment.RequestedShipment.Recipient.Tins = ti

    # ----------------------------------------------------
    # add "commercial invoice" reference as the only commodity
    def add_ci_commodity(self):

        self.addCommodity(
            cCustomsValueAmnt=self.invoice_info["Value"],
            cCustomsValueCurrency=self.invoice_info["Currency"],
            cWeightValue=self.invoice_info["Weight"],
            cDescription="See attached commercial invoice",
            cQuantity=self.invoice_info["Quantity"],
            cExportLicenseNumber=self.shipment.RequestedShipment.Shipper.Tins.Number,
            cPartNumber=1,
        )

    # ----------------------------------------------------
    # add commodity to shipment (for now, just add 1 commodity to refer to attached CI)
    def addCommodity(
        self, cCustomsValueAmnt, cCustomsValueCurrency, cWeightValue, cDescription, cQuantity, cExportLicenseNumber, cPartNumber,
    ):

        commodity = self.shipment.create_wsdl_object_of_type("Commodity")
        commodity.NumberOfPieces = str(cQuantity)
        commodity.Description = cDescription
        commodity.Quantity = cQuantity
        commodity.QuantityUnits = "EA"
        commodity.ExportLicenseNumber = cExportLicenseNumber
        commodity.PartNumber = cPartNumber
        commodity.CountryOfManufacture = "DK"

        mCustomsValue = self.shipment.create_wsdl_object_of_type("Money")
        mCustomsValue.Amount = cCustomsValueAmnt
        mCustomsValue.Currency = cCustomsValueCurrency
        commodity.CustomsValue = mCustomsValue

        commodity_weight = self.shipment.create_wsdl_object_of_type("Weight")
        commodity_weight.Value = cWeightValue
        commodity_weight.Units = "KG"
        commodity.Weight = commodity_weight

        munitPrice = self.shipment.create_wsdl_object_of_type("Money")
        munitPrice.Amount = float(round((cCustomsValueAmnt / cQuantity), 2))
        munitPrice.Currency = cCustomsValueCurrency
        commodity.UnitPrice = munitPrice

        self.mCommodities.append(commodity)

    # ----------------------------------------------------
    # add package to shipment
    def set_packaging_info(self):
        weight = self.invoice_info["Weight"]

        type = "BOX" if weight > 0.5 else "ENVELOPE"
        weight_final = float(round(weight + 0.2, 2)) if weight > 0.5 else 0.4

        self.addShippingPackage(packageWeight=weight_final, physicalPackagingType=type, packagingType=f"FEDEX_{type}")

    # ----------------------------------------------------
    # add package to shipment
    def addShippingPackage(self, packageWeight, physicalPackagingType, packagingType, packageWeightUnit="KG"):
        package_weight = self.shipment.create_wsdl_object_of_type("Weight")
        package_weight.Value = packageWeight
        package_weight.Units = packageWeightUnit

        package = self.shipment.create_wsdl_object_of_type("RequestedPackageLineItem")
        package.PhysicalPackaging = physicalPackagingType
        package.Weight = package_weight

        self.shipment.add_package(package)
        self.shipment.RequestedShipment.TotalWeight = package_weight
        self.shipment.RequestedShipment.PackagingType = packagingType

    # ----------------------------------------------------
    # add information on duties
    def setDutiesPaymentInfo(self):
        mParty = self.shipment.create_wsdl_object_of_type("Party")
        mParty.AccountNumber = self.CONFIG_OBJ.account_number
        mParty.Address = self.shipment.RequestedShipment.Recipient.Address

        mPayor = self.shipment.create_wsdl_object_of_type("Payor")
        mPayor.ResponsibleParty = mParty

        mPayment = self.shipment.create_wsdl_object_of_type("Payment")
        mPayment.PaymentType = "RECIPIENT"  # change if sender should pay duties
        mPayment.Payor = mPayor

        mCustomsValue = self.shipment.create_wsdl_object_of_type("Money")
        mCustomsValue.Amount = self.invoice_info["Value"]
        mCustomsValue.Currency = self.invoice_info["Currency"]

        ccd = self.shipment.create_wsdl_object_of_type("CustomsClearanceDetail")
        ccd.Commodities = self.mCommodities
        ccd.CustomsValue = mCustomsValue
        ccd.DutiesPayment = mPayment
        self.shipment.RequestedShipment.CustomsClearanceDetail = ccd

    # ----------------------------------------------------
    # Set ETD (electronic trade documents) settings
    def setSpecialServices(self, doc_ids):
        # construct objects
        ssr = self.shipment.create_wsdl_object_of_type("ShipmentSpecialServicesRequested")
        ssr.SpecialServiceTypes.append("ELECTRONIC_TRADE_DOCUMENTS")
        ssr.SpecialServiceTypes.append("EVENT_NOTIFICATION")

        # set up ETD details
        etd = self.shipment.create_wsdl_object_of_type("EtdDetail")
        etd.RequestedDocumentCopies = "COMMERCIAL INVOICE"

        for i, doc_id in enumerate(doc_ids, start=0):
            udrd = self.shipment.create_wsdl_object_of_type("UploadDocumentReferenceDetail")
            udrd.DocumentType = "COMMERCIAL_INVOICE" if i == 0 else "OTHER"
            udrd.DocumentId = doc_id
            udrd.Description = "Commercial_Invoice" if i == 0 else "Product_Description"
            udrd.DocumentIdProducer = "CUSTOMER"
            ssr.EtdDetail.DocumentReferences.append(udrd)

        self.shipment.RequestedShipment.SpecialServicesRequested = ssr

        # set Event Notification details
        send = self.shipment.create_wsdl_object_of_type("ShipmentEventNotificationDetail")
        send.AggregationType = "PER_SHIPMENT"

        sens = self.shipment.create_wsdl_object_of_type("ShipmentEventNotificationSpecification")
        sens.NotificationDetail.NotificationType = "EMAIL"
        sens.NotificationDetail.EmailDetail.EmailAddress = self.shipment.RequestedShipment.Recipient.Contact.EMailAddress
        sens.NotificationDetail.EmailDetail.Name = self.shipment.RequestedShipment.Recipient.Contact.PersonName
        sens.NotificationDetail.Localization.LanguageCode = "EN"
        sens.Role = "SHIPPER"
        sens.Events.append("ON_SHIPMENT")
        sens.Events.append("ON_EXCEPTION")
        sens.Events.append("ON_DELIVERY")
        sens.FormatSpecification.Type = "HTML"
        send.EventNotifications = sens
        self.shipment.RequestedShipment.SpecialServicesRequested.EventNotificationDetail = send

    # ----------------------------------------------------
    # process the shipment
    def processInternationalShipment(self):
        from shutil import copyfile

        self.shipment.RequestedShipment.ShipTimestamp = datetime.datetime.now().replace(microsecond=0).isoformat()

        # print(" ---- **** DETAILS ---- ****")
        # print(self.shipment.RequestedShipment)
        # print(self.shipment.ClientDetail)
        # print(self.shipment.TransactionDetail)
        # print("REQUESTED SHIPMENT\n\n", self.shipment.RequestedShipment)

        self.shipment.send_request()

        # print("RESPONSE\n\n", self.shipment.response)

        status = self.shipment.response.HighestSeverity

        if status == "SUCCESS" and "CompletedShipmentDetail" in self.shipment.response:
            shipment_details = self.shipment.response.CompletedShipmentDetail
            package_details = shipment_details.CompletedPackageDetails[0]
            tracking_id = package_details.TrackingIds[0].TrackingNumber
            email = self.shipment.RequestedShipment.Recipient.Contact.EMailAddress
            fedex_cost = "N/A"

            if hasattr(package_details, "PackageRating"):
                fedex_cost = package_details.PackageRating.PackageRateDetails[0].NetCharge.Amount

            # create the shipping PDF label
            ascii_label_data = package_details.Label.Parts[0].Image
            label_binary_data = binascii.a2b_base64(ascii_label_data)
            out_path = self.invoice_info["InvoiceId"] + f"_shipment_label_{tracking_id}.pdf"

            out_file = open(out_path, "wb")
            out_file.write(label_binary_data)
            out_file.close()

            # print output information
            print(
                f"- SUCCESS: Created FedEx label for invoice {self.invoice_info['InvoiceId']}\n     tracking ID: {tracking_id}\n     email: {email}\n     FedEx cost: {fedex_cost}\n     Customs value: {self.invoice_info['Value']} {self.invoice_info['Currency']}\n     Weight: {self.invoice_info['Weight']}\n     output path: {out_path}"
            )


# ----------------------------------------------------
# main script
commercial_invoice_path = "commercial_invoice_test.pdf"
product_description_1_path = "product_description_test.pdf"

sender = {
    "Company": "Sender Company",
    "Name": "Mr Smith",
    "Address": ["Address 1", "Address 2"],
    "Region": "",
    "Zip": "8230",
    "City": "Abyhoj",
    "Country": "Denmark",
    "Phone": "12345678",
    "Email": "mail@mail.com",
    "CountryCode": "DK",
    "Currency": "EUR",
    "VAT": "DK12345678",
    "Residential": False,
}

recipient = {
    "Company": "Recipient Co",
    "Name": "Contact Name",
    "Address": ["Adr1, Adr2"],
    "Region": "MN",
    "Zip": "55420",
    "City": "Bloomington",
    "Country": "United States",
    "Phone": "0123456789",
    "Email": "mail@mail.com",
    "CountryCode": "US",
    "Currency": "EUR",
    "VAT": "",
    "Residential": False,
}

invoice_info = {
    "InvoiceId": "14385",
    "Weight": 0.11,
    "Quantity": 2,
    "Value": 20.0,
    "Shipping": 25.0,
    "ShippingExpress": True,
    "Currency": "EUR",
    "InvoicePath": commercial_invoice_path,
    "Pdfs": [product_description_1_path],
}

# print output
print(f"\n- recipient: {recipient}\n- invoice_info: {invoice_info}\n")

# create FedEx Label Helper and set configuration
flh = FedexLabelHelper()
flh.setShipmentConfig(CONFIG_OBJ=CONFIG_OBJ, invoice_info=invoice_info)

# add sender & recipient info to FedEx shipment
flh.setSenderInfo(sender)
flh.setRecipientInfo(recipient)

# set packaging based on weight
flh.set_packaging_info()

# add reference to CI as only commodity info
flh.add_ci_commodity()

# set duties payment information
flh.setDutiesPaymentInfo()

# upload documents
doc_ids = flh.upload_all_documents()

# link uploaded documents as ETD and setup event notifications
flh.setSpecialServices(doc_ids)

# process shipments and create shipping labels
flh.processInternationalShipment()

答案 15 :(得分:0)

我发现这种方法在检查多个属性时更严格、更快

$null -ne $myobject.PSObject.Properties.Item("myPropertyNameToTest")

答案 16 :(得分:-1)

您可以通过以下方式进行检查:

($Member.PropertyNames -contains "Name"),这将检查Named属性

相关问题