A little background: We are working on a function that goes through hundreds of entries, similar to the following:
| City | State | Population |
|---|---|---|
| New York | New York | 8467513 |
| Los Angeles | California | 3849297 |
| Chicago | Illinois | 2696555 |
| Houston | Texas | 2288250 |
| Phoenix | Arizona | 1624569 |
| Philadelphia | Pennsylvania | 1576251 |
| San Antonio | Texas | 1451853 |
| San Diego | California | 1381611 |
| Dallas | Texas | 1288457 |
| San Jose | California | 983489 |
The raw data will be gotten using an Import-Csv. The CSV is updated on a regular basis.
We are trying to use PowerShell classes to enable people to select the City based on the State they select. Here is the MWE we have gotten so far:
$Global:StateData = Import-Csv \\path\to\city-state-population.csv
class State : System.Management.Automation.IValidateSetValuesGenerator {
[string[]] GetValidValues() {
return (($Global:StateData).State | Select-Object -Unique)
}
}
class City : System.Management.Automation.IValidateSetValuesGenerator {
[string[]] GetValidValues($State) {
return ($Global:StateData | Where-Object State -eq $State).City
}
}
function Get-Population {
param (
# Name of the state
[Parameter(Mandatory, Position = 0)]
[ValidateSet([State])]
$State,
# Name of the city
[Parameter(Mandatory, Position = 1)]
[ValidateSet([City])]
$City
)
$City | ForEach-Object {
$TargetCity = $City | Where-Object City -match $PSItem
"The population of $($TargetCity.City), $($TargetCity.State) is $($TargetCity.Population)."
}
}
Of course, according to the official documentation, GetValidValues() does not seem to accept parameter input. Is there a way to achieve this at all?
The results would need to be similar to PowerShell Function – Validating a Parameter Depending On A Previous Parameter’s Value, but the approach the post takes is beyond imagination for the amount of data we have.
Note: This is on PowerShell (Core), and not Windows PowerShell. The latter does not have the IValidateSetValuesGenerator interface.
I'm honestly not sure if you can do this with two
ValidateSetAttribute Declarations, however, you could make it work with oneValidateSetand a custom class that implements theIArgumentCompleterInterface since it has access to$fakeBoundParameters. Here is an example, that for sure needs refinement but hopefully can get you on track.Demo