Many years later, let me clarify:
Josh's answer shows a helpful simplification for testing strings for emptiness (relying on PowerShell's implicit to-Boolean conversion[1]), but it is unrelated to Tommy's (the OP's) problem.
Instead, the error message
"Failed to convert parameter value from a ResultPropertyValueCollection to a String."
implies that it is the non-null case that caused the problem, because $objDbCmd.Parameters["@telephone"].Value
expects either a string value or [DBNull]::Value
, whereas $objUser.Telephone
is of type [ResultPropertyValueCollection]
, i.e. a collection of values.
Thus, in the non-null case, a string value must be assigned, which must be derived from the collection; one option is to take the first collection element's value, another would be to join all values with a separator to form a single string, using, e.g., [string]::Join(';', $objUser.Telephone)
or, if joining the elements with spaces is acceptable (not a good idea with multiple phone numbers), simply with "$($objUser.Telephone)"
.[2]
Detecting an empty collection via [string]:IsNullOrEmpty()
actually worked, despite the type mismatch, due to how PowerShell implicitly stringifies collections when passing a value to a [string]
typed method parameter.[2]
Similarly, using implicit to-Boolean conversion works as expected with collections too: an empty collection evaluates to $false
, a non-empty one to $true
(as long as there are either at least two elements or the only element by itself would be considered $true
[1])
Therefore, one solution is to use the first telephone number entry:
$objDbCmd.Parameters["@telephone"].Value = if ($objUser.Telephone) {
$objUser.Telephone[0].ToString() # use first entry
} else {
[DBNull]::Value
}
Note: If $objUser.Telephone[0]
directly returns a [string]
, you can omit the .ToString()
call.
In PowerShell v7+ you can alternatively shorten the statement via a ternary conditional:
$objDbCmd.Parameters["@telephone"].Value =
$objUser.Telephone ? $objUser.Telephone[0].ToString() : [DBNull]::Value
[1] For a comprehensive summary of PowerShell's automatic to-Boolean conversions, see the bottom section of this answer.
[2] When implicitly converting a collection to a string, PowerShell joins the stringified elements of a collection with a single space as the separator by default; you can override the separator with the automatic $OFS
variable, but that is rarely done in practice; e.g., array 'foo', 'bar'
is converted to 'foo bar'
; note that this conversion does not apply when you call the collection's .ToString()
method explicitly, but it does apply inside expandable (interpolating) strings, e.g., "$array"
.