Stop relying on positional parameters. Use named parameters with parameter sets, and remove the ambiguity:
[CmdletBinding(DefaultParameterSetName='ByFile')]
param(
[Parameter(
Mandatory=$true,
ParameterSetName='ByFile'
)]
[ValidateScript( { $_ | Test-File } )]
[String]
$Path ,
[Parameter(
Mandatory=$true,
ParameterSetName='ByIP'
)]
[System.Net.IPAddress[]]
$IPAddress
)
$ipAddresses = if ($PSCmdlet.ParameterSetName -eq 'ByFile') {
$Path | Get-Content
} else {
$IPAddress
}
foreach ($ip in $ipAddresses) {
# do something with the IP
}
Invoke it like this:
./get-Ping.ps1 -File ./fileOfIPs.txt
or
./get-Ping.ps1 -IPAddress 10.1.2.3
./get-Ping.ps1 -IPAddress 10.0.0.10,10.0.0.20,8.8.8.8
It even supports multiple IPs given directly.
Alternative
If you must support a positional parameter that can be either, then I suggest testing the IP first:
param($addr)
$ips = if ($addr -as [System.Net.IPAddress]) { # it can be interpreted as an IP
$addr
} else {
$addr | Get-Content
}
foreach ($ip in $ips) {
#do something
}
$filein?Get-Stuff.ps1, you're calling it as.\Get-Stuff.ps1 .\ipAddress.txtand instead of pulling the content of the file, it's just printing the file name?./get-Ping.ps1 ./ipAddress.txt