No error when selecting non-existing property

前端 未结 3 1879
梦谈多话
梦谈多话 2021-01-14 12:07

I want PowerShell to throw an error when trying to select non-existing properties, but instead I get empty column as output. Example:

$ErrorActionPreference=         


        
相关标签:
3条回答
  • 2021-01-14 12:54

    You are actually using what some people would call a feature. That is a simpler rendition of using Add-Member on all the array members to add an empty column.

    In the case of Import-CSV what you do in that case is check the property names before the Select where you call them.

    $data = Import-csv C:\Temp\file.csv 
    $props = $data | Get-member -MemberType 'NoteProperty'  | Select-Object -ExpandProperty Name
    

    I can see the documentation be a little misleading when it says for Set-StrictMode:

    Prohibits references to non-existent properties of an object.

    But in this case you are not trying to get the property reference but using a function of the Select-Object cmdlet. The following would have generated an error though

    PS C:\Users\mcameron> Set-StrictMode -Version 'Latest'
    (Get-Process *ex*).Bagels
    
    The property 'Bagels' cannot be found on this object. Verify that the property exists.
    At line:2 char:1
    + (Get-Process *ex*).Bagels
    + ~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
        + FullyQualifiedErrorId : PropertyNotFoundStrict
    
    0 讨论(0)
  • 2021-01-14 12:58

    Something like this...?

    $props = 'Id','ProcessName','xxx'
    $availableProps = Get-Process *ex*|Get-Member -MemberType Properties | Select -ExpandProperty Name
    $missingProps = $props | Where-Object {-not ($availableProps -contains $_)}
    if ($missingProps) {
      Write-Error "invalid property(s) $missingProps"
      throw { [System.Management.Automation.PropertyNotFoundException] }
    }
    
    Get-Process *ex* | Select-Object $props
    
    0 讨论(0)
  • 2021-01-14 13:11

    PowerShell expanding non-existing properties to $null behaves as designed. AFAICS the only thing you could do is to explicitly check if all properties exist:

    $props = 'Id', 'ProcessName', 'xxx'
    
    $p = Get-Process *ex*
    $missing = $p | Get-Member -Type *property |
               Select-Object -Expand Name |
               Compare-Object -Reference $props |
               Where-Object { $_.SideIndicator -eq '<=' } |
               Select-Object -Expand InputObject
    
    if ($missing) {
      throw "missing property $missing."
    } else {
      $p | Select-Object $props
    }
    

    Of course you could wrap this in a custom function:

    function Select-ObjectStrict {
      [CmdletBinding()]
      Param(
        [Parameter(
          Position=0,
          Mandatory=$true,
          ValueFromPipeline=$true,
          ValueFromPipelineByPropertyName=$true
        )]$InputObject,
    
        [Parameter(
          Position=1,
          Mandatory=$true
        )][string[]]$Property
      )
    
      Process {
        $missing = $InputObject | Get-Member -Type *property |
                   Select-Object -Expand Name |
                   Compare-Object -Reference $Property |
                   Where-Object { $_.SideIndicator -eq '<=' } |
                   Select-Object -Expand InputObject
    
        if ($missing) {
          throw "missing property $missing."
        } else {
          $InputObject | Select-Object $Property
        }
      }
    }
    

    so it could be used like this:

    Get-Process *ex* | Select-ObjectStrict -Property 'Id', 'ProcessName', 'xxx'
    
    0 讨论(0)
提交回复
热议问题