Параметры Powershell, валидация и позиционирование - PullRequest
0 голосов
/ 03 мая 2019

Все, совершенно новый для сценариев PowerShell.

По разным причинам пишем очень простой сканер портов, который может принимать отдельные IP-адреса, диапазон IP-адресов и список портов.

Сценарий вызывается, параметры считываются из командной строки startIP, endIP, порт, требуется ли сканирование в случайном порядке, разрешается и т. Д.

Действительно борется со сценарием, интерпретирующим порт как IP-адрес, который отбрасывает сценарий, если endip не указан в командной строке. Попытался поэкспериментировать с проверкой параметров, но не очень далеко, был бы признателен, если бы кто-нибудь дал мне несколько указателей:

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-х ipaddresses в указанном диапазоне и подключается к порту 445 для каждого IP-адреса и выдает отчеты, если они открыты и т. Д.

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)

Что вызывает некоторую взаимную исключительность для IPAddress или inFile для командной строки, а также для портов (что требуется всегда, независимо от того, какой метод IP-адреса доставляется). Позиционный материал больше подходит для UX, так что вы можете просто использовать IP и порты без указания указания псевдонима, если вы этого пожелаете, если я думаю, что я правильно понял?

Спасибо всем. :)

Ответы [ 2 ]

1 голос
/ 05 мая 2019

Вы также можете установить первый параметр в качестве массива IP-адресов. Тогда вам нужно только отделить начальный и дополнительный конечный адрес от этого.
Единственная разница в вызове сценария или функции заключается в том, что вы разделяете два 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

Надеюсь, это поможет

1 голос
/ 03 мая 2019

Я не смог найти ничего о .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)
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...