Hi - I've dipped my toe in the waters of functions & parameters & validation, and am feeling brave enough to go further in.
I like validateset because I often want to control what people enter. Seems nice, right? So - when I use it, is it possible to have a 'nested' / 2nd level validated parameter, so that after one is chosen, the next argument is another parameter unique to it, and so on? Neither sub-parameter should even show up unless the appropriate top-level one is selected. Here's what I mean -
--
Function Get-Stuff {
param(
[parameter(ParameterSetName="Top",
Mandatory=$false,
Position=0,
HelpMessage="Source for report")]
[ValidateNotNullorEmpty()]
[ValidateSet("AD","WSUS","CSV","Textfile","Manual")]
[String]$Source = "AD",
#[magicalsparklyunicorn2ndlevelparameter()]
# ... if $source is AD, show another parameter called 'OU' (with validateset options of OU1, OU2, OU3
# ... if $source is WSUS, show another parameter called 'TargetGroup' (with validateset options of Group1, Group2, Group3)
# ... if $source is CSV or Textfile, show another parameter called 'Filename' (with validate script options of test-path & $_ -like ".ext* or whatever)
# ... if $source is Manual, show another parameter called 'Computername' (a string accepting entries separated with commas)
[parameter(Mandatory=$False,
Position=1,
HelpMessage="AD credentials")]
[ValidateNotNullOrEmpty()]
[PSCredential]$Credentials = (get-credential -UserName ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name) -message "Valid credentials" -ErrorAction Stop)
)
Begin {
If ($Source -eq "AD") {
$BaseDN = "OU="+$OU+", DC=domain,DC.local"
$Servers = get-adcomputer -SearchBase $($BaseDN) -Credential $Credentials -filter -properties * | select-object * | Sort-Object Name -ErrorAction Stop
}
If ($Source -eq "WSUS") {
$WSUSFilter = {($_.RequestedTargetGroupName -eq $TargetGroup)}
$Servers = Get-PoshWSUSClient | Where-Object $WSUSFilter | Select-Object DNSHostName,RequestedTargetGroupName
}
If ($Source -eq "Textfile") {
$Servers = (get-content -path $Source | Where-Object { $_.Trim() -ne "" } -ErrorAction Stop) | `
foreach {$_.TrimEnd()} | foreach {$_.TrimStart()}
}
If ($Source -eq "*.csv") {
$Servers = (import-csv $Inputfile -Header A | select -ExpandProperty A -ErrorAction Stop )
}
if ($Source -eq "Manual") {
$Servers = $Manual.split(',') | % {$_.trim()}
}
}
Process {
# and then various things happen
}
End{
}
}
------------------------------------------------
So it would be like this:
Get-stuff -Source AD -OU MyOU1 -Credentials $cred
Get-stuff -source WSUS -TargetGroup Production -Credentials $cred
Get-stuff -source CSV -Filename c:\temp\myservers.csv
Get-stuff -source Textfile -Filename c:\temp\myservers.txt
Get-stuff -source Manual -Computer Server1, Server2
...and only the appropriate 2nd parameter would show up after the first.
Maybe I'm missing something really obvious. Kind of hoping so. :) I've been at this all day and can't figure it out - was wondering whether dynamic parameters are what I need, but am not sure. If I use a switch instead for the top level, can that be combined with a dynamic parameter? This is my first post in here, so be gentle.
Thanks!
Lanwench