Welcome › Forums › General PowerShell Q&A › Validate Script – Validate Custom Object Data Type
- This topic has 5 replies, 5 voices, and was last updated 1 week, 5 days ago by
Participant.
-
AuthorPosts
-
-
January 7, 2021 at 8:36 am #284608
Hi All,
Attempting to do something I assumed would be straightforward but it not working as I expected. I have a simple function which accepts an array of objects, each object being a hash table (pscustomobject) of name/value pairs. Both the name and value to be of type string.
Example array can be created using:
PowerShell123456789[crayon-600826ee5c711914117303 inline="true" ][array]$factsArray$factsArray += [pscustomobject]@{name = 'name1'value = 'value1'}$factsArray += [pscustomobject]@{name = 'name2'value = 'value2'}My current validate script confirms the present of the name and value property in each array element but I would also like to confirm each of these properties are strings.
I had (incorrectly) assumed it would be as simple as $array[#].property -as [string] but this does not appear to be working.
Example validate script:
function Test-ValidateScript
{
param
(
[Parameter(Mandatory = $true)]
[ValidateScript({if(-not ($_.PSobject.Properties.name -contains 'Name'))
{
throw [System.Management.Automation.ValidationMetadataException] 'An Array Element Did Not Contain Name Property'
}if(-not ($_.PSobject.Properties.name -contains 'Value'))
{
throw [System.Management.Automation.ValidationMetadataException] 'An Array Element Did Not Contain Value Property'
}return $true
})]
[array]$testArrayVar
)}I am not concerned with what the string is, just that it is a string.
Any suggestions appreciated.
-
This topic was modified 1 week, 5 days ago by
Rich.
-
This topic was modified 1 week, 5 days ago by
-
January 7, 2021 at 9:33 am #284623
First thing to know is every PSCustomObject property name is always a string. So really you should only be concerned with values. Here are some demonstrations
PowerShell123456789101112131415161718192021222324252627282930$var = [pscustomobject]@{[int]1=2string='def'}$var.psobject.properties | ForEach-Object {"Property name {0} {1} a string" -f $_.name,("is not","is")[$_.name -is [string]]"Property value {0} {1} a string" -f $_.name,("is not","is")[$_.value -is [string]]}Property name 1 is a stringProperty value 1 is not a stringProperty name string is a stringProperty value string is a string$var = [pscustomobject]@{[int]1='abc'string='def'}$var.psobject.properties | ForEach-Object {"Property name {0} {1} a string" -f $_.name,("is not","is")[$_.name -is [string]]"Property value {0} {1} a string" -f $_.name,("is not","is")[$_.value -is [string]]}Property name 1 is a stringProperty value 1 is a stringProperty name string is a stringProperty value string is a stringNotice on the second example even though we tried to make it an int, it is a string and powershell had no issues forcing it to be a string.
Now hashtable keys can be different types.
PowerShell123456789101112131415161718192021222324252627282930$ht = @{[int]1=2string='def'}$ht.GetEnumerator() | ForEach-Object {"Hashtable key {0} is type {1}" -f $_.key,$_.key.GetType().name"Hashtable value {0} is type {1}" -f $_.value,$_.value.GetType().name}Hashtable key 1 is type Int32Hashtable value 2 is type Int32Hashtable key string is type StringHashtable value def is type String$ht = @{[int]1='abc'string='def'}$ht.GetEnumerator() | ForEach-Object {"Hashtable key {0} is type {1}" -f $_.key,$_.key.GetType().name"Hashtable value {0} is type {1}" -f $_.value,$_.value.GetType().name}Hashtable key 1 is type Int32Hashtable value abc is type StringHashtable key string is type StringHashtable value def is type String-
January 7, 2021 at 11:30 am #284647
Thanks for all the replies guys, have it working, did not realise it was as simple as GetType().Name. Tried a few methods passing the values into get-member and others but never worked this appears to.
Just to clarify some of the confusion, the script I initially posted was just an example to test getting the validation to work not the actual script itself. The input needs to be an array of name/value pairs as the actual function can accept between 0 and 50 pairs so I figured an array was best, note the array is not the only input. My goal was to validate the array being passed in as the function will be provided to colleagues and I want it to fail if each part of the array does not:
Contain a name property of type string
Contain a value property of type string
Final validation that appears to be working from initial testing is:
[ValidateScript({
if(-not ($_.PSobject.Properties.name -contains 'name'))
{
throw [System.Management.Automation.ValidationMetadataException] 'An Array Element Did Not Contain Name Property'
}if($_.name.gettype().name -ne 'string')
{
throw [System.Management.Automation.ValidationMetadataException] 'An Array Element Contained Name Property That Was Not String'
}if(-not ($_.PSobject.Properties.name -contains 'value'))
{
throw [System.Management.Automation.ValidationMetadataException] 'An Array Element Did Not Contain Value Property'
}if($_.value.gettype().name -ne 'string')
{
throw [System.Management.Automation.ValidationMetadataException] 'An Array Element Contained Value Property That Was Not String'
}return $true
})]
Thanks to all for the help
-
-
January 7, 2021 at 9:56 am #284626
I did not know, if i get you right.
You want to check if a variable is a string or not?
Like this?
“hello” -is [string]
“hello”,”world” -is [string]
-
January 7, 2021 at 10:17 am #284629
For your example, using a function for validation, it should be:
PowerShell1234567891011121314function Test-It {param ([Parameter(ValueFromPipelineByPropertyName=$true)][string]$Name,[Parameter(ValueFromPipelineByPropertyName=$true)][string]$Value)#Default\Built-in hash for passed parameters$PSBoundParameters}[pscustomobject]@{Name='Foo';Value='Faa'} | Test-It -
January 7, 2021 at 11:30 am #284650
There is a function on GitHub that may help you to achieve what you want:
PowerShell/Get-PropertyType.ps1 at master · RamblingCookieMonster/PowerShell (github.com)
-
-
AuthorPosts
- You must be logged in to reply to this topic.