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.
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.