Powershell参数,验证和定位

时间:2019-05-03 14:23:26

标签: powershell

全部,对于Powershell脚本来说还很新。

出于各种原因,编写一个非常基本的端口扫描程序,可以使用单个IP,一定范围的IP和端口列表。

调用脚本,从命令行startIP,endIP,端口读取参数,是否需要对扫描进行随机化,解析等。

如果脚本未在命令行上指定endip,则将脚本解释为将IP地址解析为IP地址是非常困难的。尝试过进行参数验证的尝试,但步伐还不算太远,如果有人可以给我一些指示,将不胜感激:

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适用于指定范围内的3个ipaddress,并为每个IP连接到端口445,并报告是否打开等。

H:>.\scan.ps1 127.0.0.1 445想要将445解释为结束IP地址,并弄乱了范围计算。有一个if语句可以比较$endipaddress是否为$null来忽略范围计算,但是出现问题是因为脚本将端口号视为$endipaddress而不将其视为$null。我如何获得脚本以意识到那里没有第二个IP,将其视为使用单个IP?已经尝试解决此问题大约一天了。

我是不是用validatescript部分将错误的树挂了起来,并不必要地使它复杂化了?还是我在正确的地方,只是错误地使用了validatescript?

谢谢!

编辑,解决方案更新!: 忙于处理其他东西,所以直到最近才有机会重新使用它。所以现在,我查看了参数集之类的东西,有了它,似乎工作得很好:

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)

这会强制在命令行的IPAddressinFile以及端口(无论提供哪种IP地址的情况下,始终需要端口)上相互排斥。位置方面的东西更多地用于UX,因此,如果我认为正确的话,可以只使用IP和不带别名的端口来指定别名吗?

谢谢大家。 :)

2 个答案:

答案 0 :(得分:1)

我找不到关于.notequals的任何信息。另外,我发现将COMMA放在下一个参数的开头,可以更轻松地移动它们。

使用参数集将是一个好主意。 https://docs.microsoft.com/en-us/powershell/developer/cmdlet/cmdlet-parameter-sets

Param(
  [Parameter(Mandatory=$true)]
  [System.Net.IPAddress]$StartIPAddress

  ,[Parameter(Mandatory=$false)]
  [ValidateScript({if($endipaddress.gettype() -ne (typeof(System.net.ipaddress)) ) {$false}})]
  [System.Net.IPAddress]$EndIPAddress

  ,[Parameter(Mandatory=$true)]
  [Int[]]$ports

  ,[Parameter(Mandatory=$false)]
  [Switch]$random

  ,[Parameter(Mandatory=$false)]
  [Switch]$resolve)
)

答案 1 :(得分:1)

您还可以将第一个参数设置为IPAddresses数组。然后,您只需将起始地址和可选的结束地址与此分开即可。
调用脚本或函数的唯一区别是,您使用逗号分隔了两个IP地址,以便PowerShell将其解释为数组。

要破坏一个简单的函数,该函数只是简单地将接收到的参数写到控制台:

function Scan {
    Param(
        [Parameter(Mandatory = $true, Position = 0)]
        [System.Net.IPAddress[]]$IPAddress,

        [Parameter(Mandatory = $false, Position = 1)]
        [Int[]]$ports,
        [Switch]$random,
        [Switch]$resolve
  )
  # split out the IP StartAddress (index [0]) and optional EndAddress (index [1])
  $StartIPAddress, $EndIPAddress = $IPAddress

  # You dont have to do funky stuff with `[ValidateScript(...)]` because you have already 
  # defined the accepted variable type by precasting to `[System.Net.IPAddress[]]`.
  # Powershell will then accept only values that are true `System.Net.IPAddress`
  # objects or variables that can be converted to that.

  Write-Host "StartIPAddress = $StartIPAddress"
  Write-Host "EndIPAddress   = $EndIPAddress"
  Write-Host "ports          = $ports"
  Write-Host "random         = $random"
  Write-Host "resolve        = $resolve"
}

使用起始地址和结束地址进行调用:

Scan 127.0.0.1, 127.0.0.3 445

输出:

StartIPAddress = 127.0.0.1
EndIPAddress   = 127.0.0.3
ports          = 445
random         = False
resolve        = False

或者仅使用起始地址

Scan 127.0.0.1 445

输出:

StartIPAddress = 127.0.0.1
EndIPAddress   = 
ports          = 445
random         = False
resolve        = False

希望有帮助