Comments 13
Знаете, можно было бы написать проще и универсальнее. Вы заново придумали функционал стандартных командлетов.
Я бы использовал test-connection и test-path. Код сокращается в разы. Выйдет как-то вот так:
Опять же, обратите внимание, что код получается не универсальным. У вас всё подогнано под 64 битную винду, где хром стоит 32 битный.
Для универсальности, тогда уж лучше получить установленное ПО через WMI, смотреть, есть ли в установленных программах Chrome.
И ещё, для кода в статье есть тег source. Так как сейчас, в таких «success» кавычках, powershell код не выполнит.
$error.Clear() #очищаем буфер ошибок Powershell
$erroractionpreference = «silentlycontinue» #подавляем вывод ошибок в консоль
$dnsresult = 0
$computername = $i.name #извлекаем имя станции
$dnsresult = [System.Net.Dns]::resolve("$computername")
if (!$error) #условие, если предыдущая команда не была завершена ошибкой
{
$ipaddress = $dnsresult.AddressList
$pingfunc = (New-Object system.net.networkinformation.ping).send("$ipaddress") #ping
if ($pingfunc.Status -eq «success»)
{
$sumreacheblepc++ #плюсуем обще количество доступных станций
$chrome = dir \\$ipaddress\C$\Program Files (x86)\Google\Chrome\Application\chrome.exe #проверка наличия Chrome
If ($chrome -ne $null) {write-host «Host $computername is reachable, use Chrome, and have ip $ipaddress»
$sumchrome++ #плюсуем количество станций с Chrome
}
Я бы использовал test-connection и test-path. Код сокращается в разы. Выйдет как-то вот так:
$computername = $i.name
if (test-connection ) {
$sumreacheblepc++
if (test-path "\\$computername\C$\Program Files (x86)\Google\Chrome\Application\chrome.exe") {$sumchrome++}
}
Опять же, обратите внимание, что код получается не универсальным. У вас всё подогнано под 64 битную винду, где хром стоит 32 битный.
Для универсальности, тогда уж лучше получить установленное ПО через WMI, смотреть, есть ли в установленных программах Chrome.
И ещё, для кода в статье есть тег source. Так как сейчас, в таких «success» кавычках, powershell код не выполнит.
+2
Ещё не забывайте про ForEach -Parallel.
0
Раз уж вы начинающий, подскажу как оптимизировать ваше художество. Ничего, я и сам начинал с подобного.
1. Вместо Where-Object {} можете использовать альяс ?{}. А вместо Select-Object просто select. Имена свойств можно указывать без аргумента -Property. Этот аргумент удобно использовать для просмотра всех свойств объекта, например | select -Property *
2. Зачем вам в Get-AD(Object, Computer,User,Group) аргумент Filter? Вы выбрали все станции, а потом отсортировывали не выключенные станции через Where-Object проделывая, считай, двойную работу. Читай вы внимательно хелп к командлетам (это кстати можно удобно делать через Get-Help -Online), узнали бы что получить сразу не выключенные станции можно так:
3. Пинг компьютера вам уже подсказали выше можно было бы сделать через Test-Connection. Уточню лишь, что используя этот командлет вне условия if вы рискуете получить не булевый результат, а массив с результатами теста, по этому если вам нужно получить результат пинга в булеву переменную используйте аргумент -Quiet.
4. Получить наличие хрома на компьютере действительно лучше посредством WMI-запроса. Командлет для всех WMI запросов один — это Get-WMIObject. Необходимый командлету параметр это -Class. Что бы получить список WMI классов можно воспользоваться свитчем -List. Нужный нам для нашей задачи класс — Win32_InstalledProgram. Ну а полный запрос наличия хрома будет выглядеть так:
Итого, если не заниматься ерундой с выводом в консоль получается вот такой лаконичный код:
Он чутка сложнее для понимания новичками, так как не использует развернутую конструкцию foreach и можно легко запутаться в ссылках на текущий объект ($_). Но мне нравится как такой код выглядит. Прошу прощения за помпезность. ;-)
1. Вместо Where-Object {} можете использовать альяс ?{}. А вместо Select-Object просто select. Имена свойств можно указывать без аргумента -Property. Этот аргумент удобно использовать для просмотра всех свойств объекта, например | select -Property *
2. Зачем вам в Get-AD(Object, Computer,User,Group) аргумент Filter? Вы выбрали все станции, а потом отсортировывали не выключенные станции через Where-Object проделывая, считай, двойную работу. Читай вы внимательно хелп к командлетам (это кстати можно удобно делать через Get-Help -Online), узнали бы что получить сразу не выключенные станции можно так:
$enablePCs = Get-ADComputer -Filter {enabled -eq $true}
3. Пинг компьютера вам уже подсказали выше можно было бы сделать через Test-Connection. Уточню лишь, что используя этот командлет вне условия if вы рискуете получить не булевый результат, а массив с результатами теста, по этому если вам нужно получить результат пинга в булеву переменную используйте аргумент -Quiet.
4. Получить наличие хрома на компьютере действительно лучше посредством WMI-запроса. Командлет для всех WMI запросов один — это Get-WMIObject. Необходимый командлету параметр это -Class. Что бы получить список WMI классов можно воспользоваться свитчем -List. Нужный нам для нашей задачи класс — Win32_InstalledProgram. Ну а полный запрос наличия хрома будет выглядеть так:
Get-WmiObject -Class Win32_InstalledProgram -ComputerName <computername> | ?{$_.Name -like "*Chrome*"} | select Name, Version, Vendor
Итого, если не заниматься ерундой с выводом в консоль получается вот такой лаконичный код:
$enablePCs = Get-ADComputer -filter {enabled -eq $true} -SearchBase "OU=Computers,ou=someou,dc=somedomain,dc=corp"
$sumchrome = 0
$sumreacheblePC = 0
$sumunreacheblePC = 0
$pcwithoutchrome = 0
$enablePCs | ForEach-Object {
if(Test-Connection -ComputerName $_.Name){
$sumreacheblePC++
if((Get-WmiObject -Class Win32_InstalledProgram | ?{$_.Name -like "*Chrome*"}) -ne $null){$sumchrome++}else{$pcwithoutchrome++}
} else {$sumunreacheblePC++}
}
Он чутка сложнее для понимания новичками, так как не использует развернутую конструкцию foreach и можно легко запутаться в ссылках на текущий объект ($_). Но мне нравится как такой код выглядит. Прошу прощения за помпезность. ;-)
+1
В коде забыл у Get-WmiObject указать -ComputerName $_.Name. Прошу прощения еще раз. Писал без проверки кода.
0
Спасибо за подсказку, учту все в следующих скриптах. Код кстати не сложный для понимания.
Про вывод в консоль вы правы, но я его использовал для отладки в основном, ну и еще нужно было собрать всю информацию в файл, просто исключил эту строку из кода.
Изначально для проверки наличия Chrome я использовал win32_product но не обнаружил в списке самого Chrome, поэтому решил проверять наличие исполняемого файла.
Про вывод в консоль вы правы, но я его использовал для отладки в основном, ну и еще нужно было собрать всю информацию в файл, просто исключил эту строку из кода.
Изначально для проверки наличия Chrome я использовал win32_product но не обнаружил в списке самого Chrome, поэтому решил проверять наличие исполняемого файла.
0
Можно поподробней про класс Win32_InstalledProgram? Я не нашел такого.
+1
Да. каждый «писатель» на повершеле должен написать свою систему сбора информации.
Это, кстати полезно.
у меня на гитхабе лежит мой вариант скриптов, тоже для этого дела, но мне было сложнее — вагон подсеток, все компьютеры по своим OU и тд — очень большая компания
Это, кстати полезно.
у меня на гитхабе лежит мой вариант скриптов, тоже для этого дела, но мне было сложнее — вагон подсеток, все компьютеры по своим OU и тд — очень большая компания
0
Sign up to leave a comment.
Сбор информации о рабочих станциях через Powershell