0

So, I'm writing a function. One of the function parameters I've created is called ObjectName and I want to use it to allow the user to specify the name of a PSObject that the function is supposed to create, and add members to. The new PSObject should be named after whatever string is supplied for this parameter.

The purpose of the function is to read a list of strings which from a file which have names and values separated by a :, split the strings by the : and use the two split strings as -Name and -Value input for the Add-Member cmdlet.

Here is an example of what the input file looks like:

User creation report
name: John Doe
 startDate: 01/01/2019
 creationTime: 2019-01-01T18:29:56.954Z
department: Sales
 locale: 
  unit: 

The code:

function New-ObjectFromFile {

    param (
        # Specify input data from file containing employee data.
        [Parameter(
            Position            = 0,
            Mandatory           = $true,
            ValueFromPipeline   = $true,
            HelpMessage         = 'Input file required.'
        )]
        [ValidateNotNullOrEmpty()]
        [string]
        $File,
        # Specify name of object to be created.
        [Parameter(
            Position            = 1,
            Mandatory           = $true,
            ValueFromPipeline   = $false,
            HelpMessage         = 'Object name required. This will be the name of the PSObject this function creates.'
        )]
        [ValidateNotNullOrEmpty()]
        [string]
        $ObjectName
    )

    # Read data from -File param
    $inputData = Get-Content -Path $File
    # Remove empty lines and non-properties from array
    $inputData = $inputData | Where-Object {$_ -like '*:*'}
    # Create new empty PSObject named after -ObjectName param
    New-Variable -Name $ObjectName -Value $(New-Object -TypeName PSObject)
    # Add array items as members to object
    foreach ($line in $inputData) {
        # Split line, max string count of 2 in order to preserve values containing ':'
        $lineSplit = $line -split ':',2
        # Remove leading and trailing whitespace from name and value
        $name = $lineSplit[0].trim()
        $value = $lineSplit[1].trim()
        # Only add non-empty properties
        if ('' -ne $value) {
            $ObjectName | Add-Member -MemberType NoteProperty -Name $name -Value $value
        }
    }
}

The two parts I think may need a different approach are the New-Object -Name $ObjectData... line (where the PSObject is created in a somewhat hacky way in order to use the provided object name) and the $ObjectName | Add-Member... line which adds each line's name and value as a NoteProperty to the object.

I have tried a number of different methods in place of the above Add-Member usage:

$($ObjectName.ToString()) | Add-Member -MemberType NoteProperty -Name $name -Value $value

Results in $providedName (name specified for -ObjectName in function call) still being an empty object devoid of any members besides default methods of a PSObject (Equals, GetHashCode, GetType, ToString)

Add-Member -MemberType NoteProperty -Name $name -Value $value -InputObject $(Get-Variable -Name $ObjectName.ToString())

Same result.

Add-Member -MemberType NoteProperty -Name $name -Value $value -InputObject $(Get-Variable -Name $($ObjectName.ToString()))

Same result.

I know the PSObject is created (empty) as expected because I have stepped through this in a shell. The Add-Member usage is where I think I'm really in need of a solution.

At this point I'm sure I'm going about this the wrong way. Am I missing something obvious? Any feedback or ideas are welcome.

EDIT: I did a lot of typing without really stating the question. How do I use $ObjectName as specified by the parameter input as input for Add-Member? I want to add members to an object but I don't know what the name of the object is until it is supplied when the function is called. I need to pass $ObjectName to Add-Member in a way that really passes whatever the object name supplied by the user is, not "ObjectName" but $userSpecifiedObjectName.

1
  • take a look at ConvertFrom-StringData. you would need to remove the description line & replace the : with =, but the result would be a hashtable that you can use to build an object. Commented Jul 10, 2019 at 5:56

1 Answer 1

1

Not exactly sure if this is what you are looking for. But this will add the ':' separated items (name: John Doe) into the PSObject you were creating. Within your foreach loop,

(Get-Variable -name $ObjectName).Value | Add-Member -MemberType NoteProperty -Name $name -Value $value

You can reference that object with

(Get-Variable -name $ObjectName).Value.Name

Is that what you were trying to do? If not, could you explain a little more?

Sign up to request clarification or add additional context in comments.

1 Comment

That did it. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.