Многопоточный сканер сети

Натолкнулся в форумах на просьбу написать сканер сети работающий в несколько потоков, но на скриптах Smile Задачка показалась мне интересной и даже полезной, поэтому родился вот такой скриптик:

ThreadPing.ps1

Param (            
[string[]]$Address = $(1..20 | %{"192.168.1.$_"}),            
[int]$Threads = 5            
)            
            
write-host "Distributing addresses around jobs"            
$JobAddresses = @{}            
$CurJob = 0            
$CurAddress = 0            
while ($CurAddress -lt $Address.count)            
{            
    $JobAddresses[$CurJob] += @($Address[$CurAddress])            
    $CurAddress++            
    if ($CurJob -eq $Threads -1)            
    {            
        $CurJob = 0            
    }            
    else            
    {            
        $CurJob++            
    }            
}            
            
$Jobs = @()            
foreach ($n in 0 .. ($Threads-1))            
{            
    Write-host "Starting job $n, for addresses $($JobAddresses[$n])"            
    $Jobs += Start-Job -ArgumentList $JobAddresses[$n] -ScriptBlock {            
        $ping = new-object System.Net.NetworkInformation.Ping            
        Foreach ($Ip in $Args)            
        {            
            trap {            
                new-object psobject -Property {            
                    Status = "Error: $_"            
                    Address = $Ip            
                    RoundtripTime = 0            
                }            
                Continue            
            }            
            $ping.send($Ip,100) | select `
                @{name="Status"; expression={$_.Status.ToString()}},             
                @{name = "Address"; expression={$Ip}}, RoundtripTime            
        }            
    }            
}            
            
write-host "Waiting for jobs"            
$ReceivedJobs = 0            
while ($ReceivedJobs -le $Jobs.Count)            
{            
    foreach ($CompletedJob in ($Jobs | where {$_.State -eq "Completed"}))            
    {            
        Receive-Job $CompletedJob | select status, address, roundtriptime            
        $ReceivedJobs ++            
        sleep 1            
    }            
}            
            
Remove-Job $Jobs            
write-host "Done."

 

У скрипта два аргумента:

  • Threads – число потоков
  • Address – диапазон ip-адресов в виде массива строк. Например чтобы просканировать адреса с 192.168.1.1 по 192.168.1.254 можно использовать следующую конструкцию: 1..254 | ${"192.168.1.$_"}

Пример использования:

PS > .\ThreadPing.ps1 -Address (1..20|%{"192.168.1.$_"}) -threads 5
Distributing addresses around jobs
Starting job 0, for addresses 192.168.1.1 192.168.1.6 192.168.1.11 192.168.1.16
Starting job 1, for addresses 192.168.1.2 192.168.1.7 192.168.1.12 192.168.1.17
Starting job 2, for addresses 192.168.1.3 192.168.1.8 192.168.1.13 192.168.1.18
Starting job 3, for addresses 192.168.1.4 192.168.1.9 192.168.1.14 192.168.1.19
Starting job 4, for addresses 192.168.1.5 192.168.1.10 192.168.1.15 192.168.1.20
Waiting for jobs

Done.
Status   Address      RoundtripTime
------   -------      -------------
TimedOut 192.168.1.2              0
TimedOut 192.168.1.7              0
Success  192.168.1.12             1
TimedOut 192.168.1.17             0
Success  192.168.1.1              0
Success  192.168.1.6              1
TimedOut 192.168.1.11             0
TimedOut 192.168.1.16             0
Success  192.168.1.3             10
TimedOut 192.168.1.8              0
TimedOut 192.168.1.13             0
TimedOut 192.168.1.18             0
TimedOut 192.168.1.4              0
TimedOut 192.168.1.9              0
TimedOut 192.168.1.14             0
TimedOut 192.168.1.19             0
TimedOut 192.168.1.5              0
TimedOut 192.168.1.10             0
TimedOut 192.168.1.15             0
TimedOut 192.168.1.20             0

Так как вывод полностью объектный, в лучших традициях PowerShell’а, то результатами легко оперировать. Например, чтобы получить лишь отзывающиеся на пинг хосты, можно использовать where:

.\ThreadPing.ps1 -Address (1..254|%{"192.168.1.$_"}) -threads 20 | 
	where {$_.status -eq "success"}

A что бы выбрать лишь адреса, достаточно добавить Select –ExpandProperty

$IPs = 1..3 | %{$s=$_; 1..254 | %{"192.168.$s.$_"}}
.\ThreadPing.ps1 -Address $Ips -threads 20 | 
	where {$_.status -eq "success"} | 
		Select -expandproperty Address

 

Да, кстати, сценарий использует фоновые работы, поэтому будет работать только в PowerShell 2.0, но я надеюсь все мои читатели уже до него обновились Smile

Опубликовано в 2.0, PowerShell, Scripting. Метки: , , . 6 комментариев »

Выкачивание драйверов с сайта HP

usbVacuum Не так давно мне понадобилось скачать драйверы и утилиты для множества моделей компьютеров HP. Учитывая что обычно для каждой модели приводится несколько десятков драйверов, скачивать их вручную и раскладывать по папкам мне показалось слишком долго и нудно. Кроме того я не хотел устанавливать какие либо менеджеры закачек которые помогли бы просто выдрать все ссылки со страницы, да они и не смогли бы правильно разложить файлы по категориям… Поэтому я решил написать простенький сценарий, который бы разбирал html страницы с драйверами для модели, понимал бы к какой категории относится драйвер или утилита, скачивал бы их, и раскладывал бы в соответствующие папки (при необходимости создавая эти папки самостоятельно).

Читать далее…

Курс по PowerShell (6434A) в моём исполнении :)

teacher1 10-12 марта, в Москве, в учебном центре Инвента, я буду читать курс по Windows PowerShell. Это официальный Microsoft’овский курс – 6434A — Automating Windows Server 2008 Administration with Windows PowerShell. С его программой можно ознакомиться тут.

Хотя в названии и фигурирует Windows Server 2008 – большая часть информации касается PowerShell вообще, независимо от операционной системы, а Windows Server 2008 используется лишь для демонстрации функционала PowerShell.

Курс подойдет и для людей совсем не знакомых с PowerShell, и для уже обладающих некоторыми знаниями. Обучение начинается с установки PowerShell и рассмотрения базового функционала. Затем идёт работа с конвейерами, форматированием вывода, и конструкциями контроля выполнения, и т.д. Ближе к концу вы научитесь использовать возможности PowerShell для работы с WMI, ADSI, COM, и .NET на реальных примерах. В курсе много лабораторных работ, что очень важно для хорошего усвоения материала.

Внимание, бонус! Курс не ограничивается программой курса 🙂 Если мы будем укладываться по времени – можно пытать меня всевозможными вопросами, я с удовольствием расскажу вам всё что знаю о PowerShell, лишь бы это было интересно и другим слушателям 🙂

Продолжительность курса – 3 дня, с 9 утра, до 17 вечера.

Стоимость – 13500 руб.

Записаться можно тут. И лучше сделать это пораньше, так как количество мест ограничено.

До встречи 🙂

Интересные примеры на PowerShell

perl Недавно натолкнулся вот на этот пост. В нём приведено несколько интересных примеров того “как в Perl одна-две строчки кода могут сделать больше, чем десять строк в каком-нибудь другом языке программирования” 😉 Мне показалось что будет интересно сравнить как эти примеры выглядели бы на PowerShell 😉 И главное – это может быть полезно тем кто уже знает Perl но сейчас изучает PS.

Как известно PowerShell очень молодой язык, и разумеется он унаследовал множество элементов других языков, и следовательно местами схож с многими из них. Я часто слышу о коде PowerShell фразы типа “О, да они же украли PHP!”, “Это же C# с более простым синтаксисом”. Но по-моему больше всего PowerShell похож на Perl. Это и не удивительно – Perl был одним из любимых языков авторов PS, и это здорово — многим хорошим особенностям в PS мы обязанны именно Perl’у.

Hats off to superstar Larry Wall and Perl, very few people and technologies that have had the level of (positive 🙂 ) impact these 2 have had on the industry.  The world is a better place because that guy was born!

Jeffrey Snover

Читать далее…

Опубликовано в PowerShell, Tips. Метки: . 26 комментариев »

Создание локального пользователя и мешающее ничто

Недавно ко мне обратились с вопросом о странном поведении достаточно простой функции. Она создаёт локального пользователя с заданным именем и паролем, и должна возвращать в качестве результата объект с двумя свойствами: UserName и Password (Ну на самом деле функция была чуть сложнее, но нам интересна только эта часть 🙂 ). Читать далее…

Опубликовано в Learn, PowerShell, Scripting, Tips. Метки: . 3 комментария »