none
PowerShell 4.0 Remove a member from a custom object? RRS feed

  • Question

  • I'm playing around with an address file that I've imported from a .csv. 

    I imported using the following: 

     PS>$lapsed= Import-CSV lapsed.csv

    This gives me a custom object, with the fields as NoteProperties 

    PS>$Lapsed |Get-Member

     

       TypeName: System.Management.Automation.PSCustomObject

     

    Name         MemberType   Definition

    ----         ----------   ----------

    Equals       Method       bool Equals(System.Object obj)

    GetHashCode  Method       int GetHashCode()

    GetType      Method       type GetType()

    ToString     Method       string ToString()

    Addressee    NoteProperty System.String Addressee=Joe Blow 

    City         NoteProperty System.String City=New York

    first        NoteProperty System.String first=Joe

    ...  


    Now I know that can add a field (i.e. member to the object using the Add-Member cmdlet

    PS>$lapsed | Add-Member -Name "fname" -MemberType NoteProperty -Value ""

     

    My question is.... Can you remove a member?  I don't see a Remove-Member cmdlet  or anything that seems to correspond to this capability.  

    Notes:

    1. Since I'm just manipulating the fields of an address list, I know that I could just edit the .csv file before Import-CSV, which is maybe what I should do...

    2. Another workaround is probably to define a custom object with the field names that I want to and then copy the fields from the original object into the custom object.   

    Thanks!  

    Thursday, April 9, 2015 1:52 PM

Answers

  • Why?

    $obj1 = [pscustomobject]@{
        'Name1' = 'Data1'
        'Name2' = 'Data2'
        'Name3' = 'Data3'
        'Name4' = 'Data4'
    }
    
    $obj1.PsObject.Members.Remove('Name2')
    
    
    Just remove it.  No problem.


    \_(ツ)_/

    • Marked as answer by lkeyes Thursday, April 9, 2015 6:14 PM
    Thursday, April 9, 2015 3:54 PM

All replies

  • Why do you need to remove a member? If you don't need it, ignore it.


    -- Bill Stewart [Bill_Stewart]

    Thursday, April 9, 2015 2:31 PM
    Moderator
  • Hi,

    If you really need an object with only the properties you want, you can do something like this:

    $obj1 = [pscustomobject]@{
        'Name1' = 'Data1'
        'Name2' = 'Data2'
        'Name3' = 'Data3'
        'Name4' = 'Data4'
    }
    
    $obj2 = $obj1 | Select Name1,Name2,Name4

    I don't see much of a need for this personally though.


    EDIT: Skip this, see jrv's post below.

    Don't retire TechNet! - (Don't give up yet - 13,225+ strong and growing)

    Thursday, April 9, 2015 2:48 PM
  • Why?

    $obj1 = [pscustomobject]@{
        'Name1' = 'Data1'
        'Name2' = 'Data2'
        'Name3' = 'Data3'
        'Name4' = 'Data4'
    }
    
    $obj1.PsObject.Members.Remove('Name2')
    
    
    Just remove it.  No problem.


    \_(ツ)_/

    • Marked as answer by lkeyes Thursday, April 9, 2015 6:14 PM
    Thursday, April 9, 2015 3:54 PM
  • Why?

    $obj1 = [pscustomobject]@{
        'Name1' = 'Data1'
        'Name2' = 'Data2'
        'Name3' = 'Data3'
        'Name4' = 'Data4'
    }
    
    $obj1.PsObject.Members.Remove('Name2')
    
    Just remove it.  No problem.


    \_(ツ)_/

    Interesting... New to me.


    Don't retire TechNet! - (Don't give up yet - 13,225+ strong and growing)

    Thursday, April 9, 2015 3:55 PM
  • If you just want to erase everything then:

    $obj1.PsObject.Members|%{$obj1.PsObject.Members.Remove($_.Name)}


    \_(ツ)_/

    Thursday, April 9, 2015 3:56 PM
  • Unfortunately it won't work directly with imported CSV files.


    \_(ツ)_/

    Thursday, April 9, 2015 4:43 PM
  • Thanks jrv and everyone!  I figured there was a way. I just think its odd that if there is an Add-Member cmdlet, there would be a corresponding Remove-Member cmdlet.    

    As for "why do I want to do this?"...  I admit my example is a bit lame, and there are workarounds. However,  it seems to me that adding or removing members of an object are fundamental to object oriented programming, and and since PS is OO, then I think object manipulation is fundamental.    --- L

    Update:

    Actually,  there is a refinement to the answer. Instead of operating on the original object, I have to go through all of the objects in the set..... so I use a For-Each Object loop: 

    PS> $lapsed | ForEach-Object ($_){$_.PsObject.Members.Remove('first')}

    This is kind of an interesting level of abstraction for my poor brain.  The variable $lapsed, shows a definition of a PSCustomObject but $lapsed is actually a collection of PSCustomObjects, one per  individual address records.  So, when I'm doing a Get-Member on $lapsed, I'm actually looking at an instance of a single record....not the whole collection of records.  (I think).   Here's what it looks like:  

    PS>$lapsed  | gm
    
    
       TypeName: System.Management.Automation.PSCustomObject
    
    Name        MemberType   Definition                                
    ----        ----------   ----------                                
    Equals      Method       bool Equals(System.Object obj)            
    GetHashCode Method       int GetHashCode()                         
    GetType     Method       type GetType()                            
    ToString    Method       string ToString()                         
    Addressee   NoteProperty System.String Addressee=Joe Blow  
    City        NoteProperty System.String City=New York               
    fname       NoteProperty System.String fname=Joe                 
    lname       NoteProperty System.String lname=                      
    org         NoteProperty System.String org=                        
    State       NoteProperty System.String State=NY                    
    Street      NoteProperty System.String Street=631 W 57TH St Apt 222
    ZIP         NoteProperty System.String ZIP=10019    




    • Edited by lkeyes Thursday, April 9, 2015 7:07 PM
    Thursday, April 9, 2015 6:19 PM
  • To understand how objects work we need to study the object hierarchy and look at the object properties in the Net library. 

    For PowerShell objects this is easy:

    Start with: https://msdn.microsoft.com/en-us/library/System.Management.Automation

    and add the object like this:

    https://msdn.microsoft.com/en-us/library/System.Management.Automation.PSObject

    Now you can get the documentation
    https://msdn.microsoft.com/en-us/library/System.Management.Automation.PSCustomObject

    Also for Net objects

    https://msdn.microsoft.com/en-us/library/System.Data.SQLClient

    The MSDN library is smart and will attempt to match the full object name to a web page.


    \_(ツ)_/



    • Edited by jrv Thursday, April 9, 2015 6:41 PM
    Thursday, April 9, 2015 6:40 PM
  • I should also note that if you use the following method you will get a more global view of the object:

    http://msdn.microsoft.com/System.Data.SQLClient

    That is just this: "msdn.microsoft.com"  plus the full class or nmespace name "System.Data.SQLClient"

    Like this

    root + / + System.String

    http://msdn.microsoft.com/system.string


    \_(ツ)_/

    Thursday, April 9, 2015 6:50 PM
  • functionalized - I had a reason to do this with object that I persist to disk with json and needed to change/add/remove some properties corresponding with an upgrade to my modules:

    function Remove-Member
    {
    [cmdletbinding()]
    param
    (
    [parameter(Mandatory,ValueFromPipeline)]
    [psobject[]]$Object
    ,
    [parameter(Mandatory)]
    [string]$Member
    )
    begin{}
    process
    {
    foreach ($o in $Object)
    {
    $o.psobject.Members.Remove($Member)
    }
    }
    }#end function Remove-Member

    Tuesday, October 31, 2017 2:25 PM