All, quite new to powershell scripting.
For various reasons, writing a very basic port scanner that can take single IPs, a range of IP and a list of ports.
Script is called, parameters read from command line startIP, endIP, port, whether you require the scan to be randomised, resolved etc.
Really struggling with the script interpreting a port as an IP address which is throwing off the script if an endip isn't specified on the command line. Have tried experimenting with parameter validation, but am not getting very far, would be grateful if someone could give me some pointers:
Param(
[Parameter(Mandatory=$true)]
[System.Net.IPAddress]$StartIPAddress,
[System.Net.IPAddress]$EndIPAddress,
[ValidateScript({if($endipaddress.gettype().notequals(typeof(System.net.ipaddress))) {$endipaddress = $null}})]
[Int[]]$ports,
[Switch]$random,
[Switch]$resolve)
H:>.\scan.ps1 127.0.0.1 127.0.0.3 445 works for the 3 ipaddresses in the range specified and connects to port 445 for each IP and reports if open etc.
H:>.\scan.ps1 127.0.0.1 445 wants to interpret 445 as the end IP address and messes with the range calculation. There is an if statement to compare if $endipaddress is $null to just ignore the range calc, but the problem arises because the script treats the port number as $endipaddress and doesn't see it as $null. How can I get the script to realise that there's not a second IP in there an treat it as using a single IP? Been trying to solve this for about a day now.
Am I barking up the wrong tree with the validatescript section and needlessly overcomplicating it? Or am I on the right lines and merely using validatescript incorrectly?
Thanks in advance!
Edit, solution update!: Been busy with other stuff, so only recently had chance to go back to it once it was just working; so now, I have looked up parameter sets and the like, have this and seems to work well:
Param(
[Parameter(Mandatory=$true,Position = 0,ParameterSetName="nofile")][System.Net.IPAddress[]]$IPAddress
,[Parameter(Mandatory=$true,Position = 1)][Int[]]$ports
,[Parameter(Mandatory=$true,ParameterSetName="file")]$inFile
,[Switch]$randomise
,[Switch]$portRange
,[Switch]$resolve
,[Switch]$delay)
Which forces some mutual exclusivity on IPAddress or inFile for the command line, as well as ports (which is required always, no matter which method IP addresses are delivered). The positional stuff is more for UX, so can just use IP and ports w/out specifying the alias should you so desire, if I think I've got the point of that correct?
Thank you to all. :)
Mandatoryattribute you've specified only applies to your first parameter. You need to specify that attribute for every parameter that is mandatory.ValidateScriptmust result in a[bool]and you cannot use it to make assignments, only to test for valid input. [grin] also also, theValidateScriptneeds to be BEFORE the thing it is validating. you see to be trying to validate the$EndIPAddressbut you have the validation AFTER that ... so it is validating the next parameter. ///// is there some reason you CANNOT use the parameter names in your calls? that is exactly why they are there ... to disambiguate what goes where. best practice is to ALWAYS use the full parameter name.scan.ps1 1.1.1.1 443andscan.ps1 1.1.1.1 443 1.1.1.4both work.validatescripthint. I need to spend some more time on this construct, I think! @Bill_Stewart thanks for the clarification.