С просторов Интернета
Важно: я не программист и не системный администратор, но мне приходиться работать одновременно с большим набором серверов и сервисов и данный скрипт я написал для собственного удобства.
Всех кому это может быть
Не все любят консоль/терминал
Думаю в этом нет противоречия, в противном случае все бы до сих пользовались консольными почтовыми клиентами и в *nix-системах не появился GUI.
Поскольку в повседневности мне приходится использовать Powershell достаточно примитивно, то для начала я попытался понять, а можно ли к нему прикрутить GUI. Оказывается можно, да еще и достаточно просто:
Add-Type -assembly System.Windows.Forms #Подключим библиотеку
$main_form = New-Object System.Windows.Forms.Form #Создаем объект с нашим "окном"
#Задаем для него параметры
$main_form.Text ='Links up' #Имя в заголовке
$main_form.Width = 300 #Ширина окна
$main_form.Height = 200 #Высота окна
$main_form.AutoSize = $true #Даем ему возможность самостоятельно изменять размер, при необходимости
$main_form.ShowDialog() #Вызываем "окно"
Добавляем к этому элемент вывода и получаем элементарное Windwows-окно
Add-Type -assembly System.Windows.Forms #Подключим библиотеку
$main_form = New-Object System.Windows.Forms.Form #Создаем переменную с нашим "окном"
#Задаем для него параметры через параметры
$main_form.Text ='Links up' #Имя в заголовке
$main_form.Width = 300 #Ширина окна
$main_form.Height = 200 #Высота окна
$main_form.AutoSize = $true #Даем ему возможность самостоятельно изменять размер, при необходимости
$Label = New-Object System.Windows.Forms.Label #Все элементы формы будут заноситься в переменные, но по факту это объекты, как любые другие переменные в Powershell
$Label.Text = "Привет! Я элементарное Windows-окно, а чего добился ты?" #Выводимый текст
$Label.Location = New-Object System.Drawing.Point(10,65) #Расположение объекта внутри формы по горизонтали и вертикали (x,y)
$Label.AutoSize = $true
$main_form.Controls.Add($Label) #добавляем созданный объект к форме, чтобы он не потерялся при выполнении скрипта
$main_form.ShowDialog() #Вызываем оскорбительно элементарное окно
Добавим динамики
Так инструмент которым я «пинговал Яндекс» и монтировал *.iso обзавёлся обособленным GUI, но этого мало. Подобным образом можно вывести информацию о доступности, но для мониторинга придется каждый раз перезапускать скрипт.
Для начала нарисуем две иконки и добавим возможность выводить изображения.
$PictureBox = New-Object system.Windows.Forms.PictureBox #Объект для вывода изображений называется вполне логично
$PictureBox.width = 10
$PictureBox.height = 10
$PictureBox.location = New-Object System.Drawing.Point(178,12)
#Вот тут мы переходим к делу привязываем выводимую картинку к результату проверки доступности узла используя командлет
#<b>test-connection</b>, где:
#-Count - передает кол-во запросов
#-computer - IP или доменное имя для запроса
#-quiet - для того чтобы нам вернулось только Boolean значение
if ((test-connection -Count 1 -computer ya.ru -quiet) -eq $True) {
$PictureBox.imageLocation = "C:\Test\yes.png" #Объект обращается к соответствующей картинке
}
Else {
$PictureBox.imageLocation = "C:\Test\no.png" #Объект обращается к соответствующей картинке
}
$PictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$main_form.Controls.Add($PictureBox)
И еще добавим кнопку, чтобы была возможность обновлять показания.
$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(100,150)
$Button.Size = New-Object System.Drawing.Size(80,30)
$Button.Text = "Reload"
# Вешаем на событие нажатия кнопки обращение каждого PictureBox согласно ранее описанной логике
$Button.Add_Click({
if ((Test-Connection -Count 1 -computer ya.ru -quiet) -eq $True)
{$PictureBox.imageLocation = "C:\Test\yes.png"}
Else {$PictureBox.imageLocation = "C:\Test\no.png"}
if ((Test-Connection -Count 1 -computer 8.8.8.8 -quiet) -eq $True)
{$PictureBox1.imageLocation = "C:\Test\yes.png"}
Else {$PictureBox1.imageLocation = "C:\Test\no.png"}
})
$main_form.Controls.Add($Button)
Чудесно, теперь в продакшн!?
Вручную прописав около полудюжины хостов я вдруг понял одну вещь — а ведь этот проект закончиться, хосты поменяют и мне придется каждый раз править скрипт. С одной стороны ничего страшного, это же решение для себя любимого. С другой стороны
Add-Type -assembly System.Windows.Forms #Подключим библиотеку
$main_form = New-Object System.Windows.Forms.Form #Создаем переменную с нашим "окном"
#Задаем для него параметры через параметры
$main_form.Text ='Links up' #Имя в заголовке
$main_form.Width = 300 #Ширина окна
$main_form.Height = 200 #Высота окна
$main_form.AutoSize = $true #Даем ему возможность самостоятельно изменять размер, при необходимости
$Label = New-Object System.Windows.Forms.Label #Все элементы формы будут заноситься в переменные, но по факту это объекты, как любые другие переменные в Powershell
$Label.Text = "ya.ru ............................" #Выводимый текст
$Label.Location = New-Object System.Drawing.Point(15,10) #Расположение объекта внутри формы по горизонтали и вертикали (x,y)
$Label.AutoSize = $true
$Label1 = New-Object System.Windows.Forms.Label #Все элементы формы будут заноситься в переменные, но по факту это объекты, как любые другие переменные в Powershell
$Label1.Text = "8.8.8.8 ............................" #Выводимый текст googl-овский DNS-ник
$Label1.Location = New-Object System.Drawing.Point(15,30) #Расположение объекта внутри формы по горизонтали и вертикали (x,y)
$Label1.AutoSize = $true
$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "192.168.x.x ............................"
$Label2.Location = New-Object System.Drawing.Point(15,50)
$Label2.AutoSize = $true
$Label3 = New-Object System.Windows.Forms.Label
$Label3.Text = "192.168.x.x ............................"
$Label3.Location = New-Object System.Drawing.Point(15,70)
$Label3.AutoSize = $true
$Label4 = New-Object System.Windows.Forms.Label
$Label4.Text = "10.0.x.x ............................"
$Label4.Location = New-Object System.Drawing.Point(15,90)
$Label4.AutoSize = $true
$Label5 = New-Object System.Windows.Forms.Label
$Label5.Text = "162.102.x.x ............................"
$Label5.Location = New-Object System.Drawing.Point(15,110)
$Label5.AutoSize = $true
$PictureBox = New-Object system.Windows.Forms.PictureBox #Объект для вывода изображений называется вполне логично
$PictureBox.width = 10
$PictureBox.height = 10
#Вот тут мы переходим к делу привязываем выводимую картинку к результату проверки доступности узла используя командлет
#<b>test-connection</b>, где:
#-Count - передает кол-во запросов
#-computer - IP или доменное имя для запроса
#-quiet - для того чтобы нам вернулось только Boolean значение
$PictureBox.location = New-Object System.Drawing.Point(235,12)
if ((test-connection -Count 1 -computer ya.ru -quiet) -eq $True) {
$PictureBox.imageLocation = "C:\Test\yes.png" #Объект обращается к соответствующей картинке
}
Else {
$PictureBox.imageLocation = "C:\Test\no.png" #Объект обращается к соответствующей картинке
}
$PictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox1 = New-Object system.Windows.Forms.PictureBox #Объект для вывода изображений называется вполне логично
$PictureBox1.width = 10
$PictureBox1.height = 10
$PictureBox1.location = New-Object System.Drawing.Point(235,32)
if ((test-connection -Count 1 -computer 8.8.8.8 -quiet) -eq $True) {
$PictureBox1.imageLocation = "C:\Test\yes.png" #Объект обращается к соответствующей картинке
}
Else {
$PictureBox1.imageLocation = "C:\Test\no.png" #Объект обращается к соответствующей картинке
}
$PictureBox1.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox2 = New-Object system.Windows.Forms.PictureBox #Объект для вывода изображений называется вполне логично
$PictureBox2.width = 10
$PictureBox2.height = 10
$PictureBox2.location = New-Object System.Drawing.Point(235,52)
if ((test-connection -Count 1 -computer 192.168.x.x -quiet) -eq $True) {
$PictureBox2.imageLocation = "C:\Test\yes.png" #Объект обращается к соответствующей картинке
}
Else {
$PictureBox2.imageLocation = "C:\Test\no.png" #Объект обращается к соответствующей картинке
}
$PictureBox2.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox3 = New-Object system.Windows.Forms.PictureBox #Объект для вывода изображений называется вполне логично
$PictureBox3.width = 10
$PictureBox3.height = 10
$PictureBox3.location = New-Object System.Drawing.Point(235,72)
if ((test-connection -Count 1 -computer 192.168.x.x -quiet) -eq $True) {
$PictureBox3.imageLocation = "C:\Test\yes.png" #Объект обращается к соответствующей картинке
}
Else {
$PictureBox3.imageLocation = "C:\Test\no.png" #Объект обращается к соответствующей картинке
}
$PictureBox3.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox4 = New-Object system.Windows.Forms.PictureBox #Объект для вывода изображений называется вполне логично
$PictureBox4.width = 10
$PictureBox4.height = 10
$PictureBox4.location = New-Object System.Drawing.Point(235,92)
if ((test-connection -Count 1 -computer 10.0.x.x -quiet) -eq $True) {
$PictureBox4.imageLocation = "C:\Test\yes.png" #Объект обращается к соответствующей картинке
}
Else {
$PictureBox4.imageLocation = "C:\Test\no.png" #Объект обращается к соответствующей картинке
}
$PictureBox1.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox5 = New-Object system.Windows.Forms.PictureBox #Объект для вывода изображений называется вполне логично
$PictureBox5.width = 10
$PictureBox5.height = 10
$PictureBox5.location = New-Object System.Drawing.Point(235,112)
if ((test-connection -Count 1 -computer 162.102.x.x -quiet) -eq $True) {
$PictureBox5.imageLocation = "C:\Test\yes.png" #Объект обращается к соответствующей картинке
}
Else {
$PictureBox5.imageLocation = "C:\Test\no.png" #Объект обращается к соответствующей картинке
}
$PictureBox5.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(100,150)
$Button.Size = New-Object System.Drawing.Size(80,30)
$Button.Text = "Reload"
# Вешаем на событие нажатия кнопки обращение каждого PictureBox согласно ранее описанной логике
$Button.Add_Click({
if ((Test-Connection -Count 1 -computer ya.ru -quiet) -eq $True)
{$PictureBox.imageLocation = "C:\Test\yes.png"}
Else {$PictureBox.imageLocation = "C:\Test\no.png"}
if ((Test-Connection -Count 1 -computer 8.8.8.8 -quiet) -eq $True)
{$PictureBox1.imageLocation = "C:\Test\yes.png"}
Else {$PictureBox1.imageLocation = "C:\Test\no.png"}
if ((Test-Connection -Count 1 -computer 192.168.x.x -quiet) -eq $True)
{$PictureBox2.imageLocation = "C:\Test\yes.png"}
Else {$PictureBox2.imageLocation = "C:\Test\no.png"}
if ((Test-Connection -Count 1 -computer 192.168.x.x -quiet) -eq $True)
{$PictureBox3.imageLocation = "C:\Test\yes.png"}
Else {$PictureBox3.imageLocation = "C:\Test\no.png"}
if ((Test-Connection -Count 1 -computer 10.0.x.x -quiet) -eq $True)
{$PictureBox4.imageLocation = "C:\Test\yes.png"}
Else {$PictureBox4.imageLocation = "C:\Test\no.png"}
if ((Test-Connection -Count 1 -computer 162.102.x.x -quiet) -eq $True)
{$PictureBox5.imageLocation = "C:\Test\yes.png"}
Else {$PictureBox5.imageLocation = "C:\Test\no.png"}
})
$main_form.Controls.Add($Label) #добавляем созданный объект к форме, чтобы он не потерялся при выполнении скрипта
$main_form.Controls.Add($Label1)
$main_form.Controls.Add($Label2)
$main_form.Controls.Add($Label3)
$main_form.Controls.Add($Label4)
$main_form.Controls.Add($Label5)
$main_form.Controls.Add($PictureBox)
$main_form.Controls.Add($PictureBox1)
$main_form.Controls.Add($PictureBox2)
$main_form.Controls.Add($PictureBox3)
$main_form.Controls.Add($PictureBox4)
$main_form.Controls.Add($PictureBox5)
$main_form.Controls.Add($Button)
$main_form.ShowDialog() #Вызываем оскорбительно элементарное окно
Даже если соблюдать чистоту и придерживаться структуры то периодическое редактирование будет вызывать не самые приятные ощущения.
Для начала выносим проверку доступности в отдельную функцию, а путь к каталогу в отдельную переменную:
$script_path = "C:\Test\PS ping"
#Переезжаем в финкцию уже созданный объект PictureBox и IP-адресс который нужно проверить.
#На выходе оно меняет подгружаемую картинку.
function get_status($PictureBox,$path_ip) {
if ((Test-Connection -Count 1 -computer $path_ip -quiet) -eq $True)
{$PictureBox.imageLocation = $script_path + "\yes.png"}
Else {$PictureBox.imageLocation = $script_path + "\no.png"}
}
Вынесем данные о хосте во внешний файл path.txt, записывая в виде «ip/host-functional-name/», а в документе будем принимать их в массивы. Так же сделаем расчет положения по Y более автоматизированным. Все это дает нам возможность создавать Label`ы и checkbox`ы вызовом функции:
#создаем описательную линию, на вход идут: объект Label, IP-адресс, описание и позиция по оси Y
Function Create_line($label,$path_ip,$caption, $top){
$label.Location = New-Object System.Drawing.Point(1, $top)
$label.text = $path_ip+$caption
$label.font = $font
$Label.AutoSize = $true
}
#создаем индикатор для описательной линию, на вход идут: объект PictureBox, IP-адресс и позиция по оси Y
Function Create_link($PictureBox,$path_ip, $top){
$PictureBox.width = 10
$PictureBox.height = 10
$PictureBox.location = New-Object System.Drawing.Point(210,$top)
get_status -PictureBox $PictureBox -path_ip $path_ip
$PictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
}
$line = Get-content -LiteralPath $script_path"\path.txt" #вытаскиваем данные о необходимых хостах
$len = $line.Length #вычисляем длину, а точнее массив длин каждой строки
$i = 0
#далее объявляем массивы которые понадобятся дальше
$ip = @() #массив ip
$capt = @() #массив описания
$Labels =@() #массив Label
$PictureBoxs =@() #массив PictureBox
while($i -lt $len){
$f = $line[$i].IndexOf("/") #вычисляем позицию начала описания
$l = $line[$i].LastIndexOf("/") #вычисляем позицию конца описания
$ip += $line[$i].Substring(0,$f) #вытаскиваем ip
$capt += $line[$i].Substring($f+1,$l-$f-1) #вытаскиваем описание
#создаем поле Label
Create_line -label ($label_obj = New-Object System.Windows.Forms.Label) -path_ip $ip[$i] -caption $capt[$i] -top $label_from_top
#создаем поле PictureBox
Create_link -PictureBox ($PictureBox_obj = New-Object system.Windows.Forms.PictureBox) -path_ip $ip[$i] -top $label_from_top
$label_from_top += 15 #делаем "шаг" по оси Y
$Labels += $label_obj #вносим созданный Label в общий массив
$PictureBoxs += $PictureBox_obj #вносим созданный PictureBox в общий массив
$main_form.Controls.Add($Labels[$i])
$main_form.Controls.Add($PictureBoxs[$i])
$i +=1
}
Добавим место для вывода времени последней проверки, потому что это удобно, и немого дополним действие при нажатии на кнопку.
$Label0 = New-Object System.Windows.Forms.Label
$Label0.Text = Get-Date
$Label0.Location = New-Object System.Drawing.Point(80,180)
$Label0.AutoSize = $true
$main_form.Controls.Add($Label0)
$Button.Add_Click({
while($i -lt $len){
get_status -PictureBox $PictureBoxs[$i] -path_ip $ip[$i]
$i +=1
}
$Label0.Text = Get-Date
})
А так же я присоединил небольшую фитчу
Add-Type -AssemblyName System.Speech
$voice = New-Object System.Speech.Synthesis.SpeechSynthesizer
$voice.Rate = 5
$voice.Speak("Ворнинг! Ворнинг! Байз из андер аттак!")
Так что после нескольких украшательств и приведения к читабельному
Add-Type -AssemblyName System.Speech
Add-Type -assembly System.Windows.Forms
$script_path = "C:\PS ping"
$label_from_top = 10
$voice = New-Object System.Speech.Synthesis.SpeechSynthesizer
$voice.Rate = 5
#Переезжаем в финкцию уже созданный объект PictureBox и IP-адресс который нужно проверить.
#На выходе оно меняет подгружаемую картинку.
function get_status($PictureBox,$path_ip) {
if ((Test-Connection -Count 1 -computer $path_ip -quiet) -eq $True) {
$PictureBox.imageLocation = $script_path + "\yes.png"
}
Else {
$PictureBox.imageLocation = $script_path + "\no.png"
$voice.Speak("Ошибка! Хост " + $path_ip + ", недоступен!")
}
}
#создаем описательную линию, на вход идут: объект Label, IP-адресс, описание и позиция по оси Y
Function Create_line($label,$path_ip,$caption, $top){
$label.Location = New-Object System.Drawing.Point(1, $top)
$label.text = $path_ip+$caption
$label.font = $font
$Label.AutoSize = $true
}
#создаем индикатор для описательной линию, на вход идут: объект PictureBox, IP-адресс и позиция по оси Y
Function Create_link($PictureBox,$path_ip, $top){
$PictureBox.width = 10
$PictureBox.height = 10
$PictureBox.location = New-Object System.Drawing.Point(210,$top)
get_status -PictureBox $PictureBox -path_ip $path_ip
$PictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
}
$main_form = New-Object System.Windows.Forms.Form
$main_form.Text ='Links up' #Имя в заголовке
$main_form.Width = 300 #Ширина окна
$main_form.Height = 200 #Высота окна
$main_form.AutoSize = $true #Даем ему возможность самостоятельно изменять размер, при необходимости
$main_form.TopMost = $true #Это очень важная штука, она дает возможность закрепить окно поверх других
$line = Get-content -LiteralPath $script_path"\path.txt" #вытаскиваем данные о необходимых хостах
$len = $line.Length #вычисляем длину, а точнее массив длин каждой строки
$i = 0
#далее объявляем массивы которые понадобятся дальше
$ip = @() #массив ip
$capt = @() #массив описания
$Labels =@() #массив Label
$PictureBoxs =@() #массив PictureBox
while($i -lt $len){
$f = $line[$i].IndexOf("/") #вычисляем позицию начала описания
$l = $line[$i].LastIndexOf("/") #вычисляем позицию конца описания
$ip += $line[$i].Substring(0,$f) #вытаскиваем ip
$capt += $line[$i].Substring($f+1,$l-$f-1) #вытаскиваем описание
#создаем поле Label
Create_line -label ($label_obj = New-Object System.Windows.Forms.Label) -path_ip $ip[$i] -caption $capt[$i] -top $label_from_top
#создаем поле PictureBox
Create_link -PictureBox ($PictureBox_obj = New-Object system.Windows.Forms.PictureBox) -path_ip $ip[$i] -top $label_from_top
$label_from_top += 15 #делаем "шаг" по оси Y
$Labels += $label_obj #вносим созданный Label в общий массив
$PictureBoxs += $PictureBox_obj #вносим созданный PictureBox в общий массив
$main_form.Controls.Add($Labels[$i])
$main_form.Controls.Add($PictureBoxs[$i])
$i +=1
}
#это поле с последним временем проверки
$Label0 = New-Object System.Windows.Forms.Label
$Label0.Text = Get-Date
$Label0.Location = New-Object System.Drawing.Point(80,180)
$Label0.AutoSize = $true
# Вешаем на событие нажатия кнопки обращение каждого PictureBox согласно ранее описанной логике
$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(100,200)
$Button.Size = New-Object System.Drawing.Size(80,30)
$Button.Text = "Reload"
$Button.Add_Click({
while($i -lt $len){
get_status -PictureBox $PictureBoxs[$i] -path_ip $ip[$i]
$i +=1
}
$i = 0
$Label0.Text = Get-Date
})
$main_form.Controls.Add($Button)
$main_form.Controls.Add($Label0)
$main_form.ShowDialog()
Послесловие
Надеюсь кому-то данный туториал будет полезен. Если же вы такое чуть-ли не с пеленок делали, то поздравляю, я — не делал. Но я готов выслушать ваши комментарии и предложения.
Для меня самого было приятно покопаться и собрать вот такую небольшую, но полезную в быту утилиту. В планах еще стоит реализовать добавления и удаления узлов из GUI, а так же сделать
Последняя версия скрипта на GitHub
Комментарии (16)
IDDQDesnik
15.08.2019 14:08Не работает на Windows 7 @ Powershell 2.0
AlexUl Автор
15.08.2019 14:12Код не идеален и проверялся только на PSversion 4.0 и 5.1, под Win10, WinServ 2012 и WinServ 2008.
Можете поделиться, на что жалуется?IDDQDesnik
15.08.2019 14:15+1Заголовок спойлераPS C:\PS ping> C:\PS ping\script.ps1
Произошла ошибка при вызове метода, так как [System.Object[]] не содержит метод с именем "Substring".
C:\PS ping\script.ps1:42 знак:27
+ $line = $data.Substring <<<< (0,47)
+ CategoryInfo : InvalidOperation: (Substring:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:51 знак:16
+ $f = $line[ <<<< $i].IndexOf("/")
+ CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:52 знак:16
+ $l = $line[ <<<< $i].LastIndexOf("/")
+ CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:53 знак:18
+ $ip += $line[ <<<< $i].Substring(0,$f)
+ CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:54 знак:19
+ $capt += $line[ <<<< $i].Substring($f+1,$l-$f-1)
+ CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Test-Connection : Не удается проверить аргумент для параметра "ComputerName". Аргумент пустой или имеет значение NULL. Укажите не пустой аргумент, не имеющий значение NULL, после чего повторите выполнение команды.
C:\PS ping\script.ps1:10 знак:41
+ if ((Test-Connection -Count 1 -computer <<<< $path_ip -quiet) -eq $True) {
+ CategoryInfo : InvalidData: (:) [Test-Connection], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:51 знак:16
+ $f = $line[ <<<< $i].IndexOf("/")
+ CategoryInfo : InvalidOperation: (1:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:52 знак:16
+ $l = $line[ <<<< $i].LastIndexOf("/")
+ CategoryInfo : InvalidOperation: (1:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:53 знак:18
+ $ip += $line[ <<<< $i].Substring(0,$f)
+ CategoryInfo : InvalidOperation: (1:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:54 знак:19
+ $capt += $line[ <<<< $i].Substring($f+1,$l-$f-1)
+ CategoryInfo : InvalidOperation: (1:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Test-Connection : Не удается проверить аргумент для параметра "ComputerName". Аргумент пустой или имеет значение NULL. Укажите не пустой аргумент, не имеющий значение NULL, после чего повторите выполнение команды.
C:\PS ping\script.ps1:10 знак:41
+ if ((Test-Connection -Count 1 -computer <<<< $path_ip -quiet) -eq $True) {
+ CategoryInfo : InvalidData: (:) [Test-Connection], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:51 знак:16
+ $f = $line[ <<<< $i].IndexOf("/")
+ CategoryInfo : InvalidOperation: (2:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:52 знак:16
+ $l = $line[ <<<< $i].LastIndexOf("/")
+ CategoryInfo : InvalidOperation: (2:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:53 знак:18
+ $ip += $line[ <<<< $i].Substring(0,$f)
+ CategoryInfo : InvalidOperation: (2:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Не удается индексировать в массив NULL.
C:\PS ping\script.ps1:54 знак:19
+ $capt += $line[ <<<< $i].Substring($f+1,$l-$f-1)
+ CategoryInfo : InvalidOperation: (2:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Test-Connection : Не удается проверить аргумент для параметра "ComputerName". Аргумент пустой или имеет значение NULL. Укажите не пустой аргумент, не имеющий значение NULL, после чего повторите выполнение команды.
C:\PS ping\script.ps1:10 знак:41
+ if ((Test-Connection -Count 1 -computer <<<< $path_ip -quiet) -eq $True) {
+ CategoryInfo : InvalidData: (:) [Test-Connection], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand
AlexUl Автор
15.08.2019 14:45Вижу что не находит метод «Substring», но с чем это связано: мой код, версия ОС или версия Powershell — не могу сказать. Может кто-то с большим опытом сможет указать на причину.
К сожалению, сейчас нет возможности протестировать в похожих условиях, но как только появится — обязательно проверю и отпишусь.
IDDQDesnik
15.08.2019 15:24И еще вдогонку:
Windows server 2016 @ Powershell 5Запускается, выдавая первую ошибку. После нажатия Reload выдает 2 и 3.
Windows PowerShell
(C) Корпорация Майкрософт (Microsoft Corporation), 2016. Все права защищены.
PS > $PSVersionTable
Name Value
---- -----
PSVersion 5.1.14393.3053
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.3053
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PS C:\PS ping> .\script.ps1
Исключение при вызове "Speak" с "1" аргументами: "Обнаружена ошибка звукового устройства. - Error Code: 0x2"
C:\PS ping\script.ps1:15 знак:3
+ $voice.Speak("Ошибка! Хост " + $path_ip + ", недоступен!")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : AudioException
Не удается найти свойство "imageLocation" для данного объекта. Убедитесь, что оно существует и его можно задать.
C:\PS ping\script.ps1:11 знак:3
+ $PictureBox.imageLocation = $script_path + "\yes.png"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
Исключение при вызове "Speak" с "1" аргументами: "Операция является недопустимой из-за текущего состояния объекта."
C:\PS ping\script.ps1:15 знак:3
+ $voice.Speak("Ошибка! Хост " + $path_ip + ", недоступен!")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
Cancel
AlexUl Автор
15.08.2019 15:34Исключение при вызове «Speak» с «1» аргументами: «Обнаружена ошибка звукового устройства. — Error Code: 0x2»
Первое логично, на серверах редко подразумевается наличие динамика.
C:\PS ping\script.ps1:15 знак:3
+ $voice.Speak(«Ошибка! Хост » + $path_ip + ", недоступен!")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo: NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId: AudioException
Add-Type: Cannot find path 'C:\PS ping\System.Windows.Forms.dll' because it does not exist.
Странно.
At C:\PS ping\script.ps1:2 char:1
+ Add-Type -assembly System.Windows.Forms
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo: ObjectNotFound: (C:\PS ping\System.Windows.Forms.dll:String) [Add-Type], ItemNotFoundException
+ FullyQualifiedErrorId: PathNotFound,Microsoft.PowerShell.Commands.AddTypeCommand
Давайте так, хоть где-то удалось запустить? =)
IDDQDesnik
15.08.2019 15:45PS 5 хоть и ругается, но работает.
Про динамик понятно (1 и 3 ошибки), просто по хорошему стоит сначала проверять его наличие. А вторая ошибка явный баг.
Нерабочий PS 6 это оказывается «фича» techcommunity.microsoft.com/t5/Windows-PowerShell/Powershell-Core-loading-assemblies/m-p/355539 stackoverflow.com/questions/57212545/how-to-add-some-types-in-powershell-6-i-can-do-in-powershell-5 возможно заработает в 7.
osipov_dv
15.08.2019 14:45Что только не придумают чтобы ставить zabbix… (можно вписать любую систему мониторинга)
Если много свободного времени, то лучше его потратить на настройку системы, а не ее написание.
vs_starosta
15.08.2019 17:421. Вы уже рисуете точки. Что мешает вам нарисовать зеленый и красный квадратик system.drawing.graphics.fillrectangle? Тогда вам ненужны эти картинки-лампочки.
2. Зачем вы парсите тектовый файл? Скрипт сам по себе текстовый файл. Объявите хэш таблицу с ip и описнаиями в начале скрипта и пробегайте её в цикле. Надо добавить что-то новое, убрать старое — открыли блокнотом и поправили одну переменную.
HomeDimoN
16.08.2019 09:42+1Как вставить свою иконку в формуРесурс храниться внутри скрипта.
#каринка в base64 base64IconString = "iVB...mCC" $bitmap = New-Object System.Windows.Media.Imaging.BitmapImage $bitmap.BeginInit() $bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64IconString) $bitmap.EndInit() $bitmap.Freeze() $form.Icon = $bitmap
почти таким же способом можно подгрузить и другие ресурсыAlexUl Автор
16.08.2019 10:09Формы проще рисовать через XAML (есть графические редкаторы).
Возможно, но я в тех туториолах что я находил для этой утилиты, была такая примитивная реализация.
Для уведомления можно сделать не только звук но и Baloon Popup в трее.
Любопытно, особенно то, что в спойлерах, возьму на заметку. =)
censor2005
«Я не программист», говорите? По-моему, именно такие утилиты выдают программиста )
AlexUl Автор
Программисты пишут сами для себя утилиты? =)
Мне казалось это удел всех, кто в какой-то момент понимает что нужна автоматизация.