Get-Random -InputObject @('zzz', 'aaa', '')
Get-Random @('zzz', 'aaa', '')
InputObject parameter position value is 1, so these command should work the same way and return one of the array elements.
While the second command works, first command produces error:
Get-Random : Cannot validate argument on parameter 'InputObject'. The argument is null or empty. Provide an argument th
at is not null or empty, and then try the command again.
At line:1 char:25
+ Get-Random -InputObject @('zzz', 'aaa', '')
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Random], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetRandomCommand
> $PSVersionTable
Name Value
---- -----
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.3
BuildVersion 3.0.0.0
WSManStackVersion 3.0
PSVersion 6.0.0-alpha
CLRVersion
PSEdition Core
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
GitCommitId v6.0.0-alpha.18
Name Value
---- -----
PSVersion 5.1.15063.138
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.15063.138
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
I'm seeing this behaviour too.
$DomainListSource = "https://raw.githubusercontent.com/opendns/public-domain-lists/master/opendns-top-domains.txt"
$domainlistMaster = (Invoke-RestMethod -useBasicParsing -uri $domainListSource) -split "`n"
Get-Random $domainlistMaster -Count 50
Get-Random : Cannot validate argument on parameter 'InputObject'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
Name Value
---- -----
PSVersion 5.0.10586.117
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.10586.117
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
This is a nasty bug in parameter binding.
@SteveL-MSFT @daxian-dbw @mklement0 for information.
This isn't an issue in the parameter binder. The default parameter set is for -Maximum, not -InputObject. InputObject has [ValidateNotNullOrEmpty] whereas Maximum does not. This attribute also checks if the collection contains $null (or empty string which is equivalent for strings). And this is what's causing the error message. Removing that attribute "fixes" this issue. Would need to think through any side effects. Since that parameter is mandatory, you can't pass in $null anyways.
@benny-gold: Your example is missing the -InputObject parameter for reproducing the symptom; as an aside: given that the list you're retrieving by definition has no line-internal spaces, the better command to use is $domainlistMaster = -split (Invoke-RestMethod -useBasicParsing -uri $domainListSource), which bypasses the problem.
@SteveL-MSFT:
Removing the ValidateNotNullOrEmpty strikes me as the right thing to do, because there is no reason to prevent pulling random elements from collections only because they happen to have empty elements.
Get-Random -InputObject $null), but (a) with an [object[]]-typed parameter that emptiness check is invariably also applied to the _elements_ of the array individually; and (b), even an empty scalar isn't worth preventing, if it is explicitly passed (which is by definition the case here, given that the parameter is mandatory), so not only should [ValidateNotNullOrEmpty] be removed, [AllowNull] should be added.As for what parameter is bound with a _positional_ argument:
Due to trickery in GetRandomCommand.cs -Maximum is _ultimately not_ bound if its argument is an _array_: the code checks for an array-valued argument and, if so, assigns to InputObject instead.
The upshot is:
Using an array _positionally_ accidentally _bypasses_ the ValidateNotNullOrEmpty validation attribute, because the argument is _initially_ bound to -Maximum, which doesn't have this attribute; therefore, it is only positional use with an array that currently - accidentally - exhibits the desired behavior.
The trickery enables questionable commands such as Get-Random -Maximum (1..10) -Count 3, which is effectively the same as Get-Random -InputObject (1..10) -Count 3
I'm also thinking that removing [ValidateNotNullOrEmpty] is the right thing and shouldn't have any negative side effects. I'll submit a PR.
:tada:This issue was addressed in #10644, which has now been successfully released as v7.0.0-preview.5.:tada:
Handy links:
Most helpful comment
I'm also thinking that removing
[ValidateNotNullOrEmpty]is the right thing and shouldn't have any negative side effects. I'll submit a PR.