ITСooky

IT-рецепты съедобные и не очень!

Powershell почему бы и нет! Пробую сделать тоже что и в bash WSL!

дата 18.09.2019

Опять все из-за Linkedin’а и потому что пробный период на Windows еще не закончился, его кстати можно продлевать. Простейший курс учим Powershell 5.0 абсолютно ничего конкретного, но объясняют как пользоваться, как оно работает вообще!

Пишем в поиске «po» и запускаем как на картинке!

Первая команда посмотрим версию
get-host | select-object version

Версия 5.1 хотя википедия сообщает что есть весрия и 6 и 7 уже, ну ладно…

OFFTOP:Немного отступлю от темы…
Через Ubuntu Software ставим powershell — да он как бы «кроссплатформенный». На Ubuntu powershell, кстати, верси 6.2 юхууу ит вис виндовс!

Была надежда что из линукса можно будет подключиться к Powershell на виндовс машине, для удобства написания скриптов, но…

На Windows надо активировать соответствующий сервис, при этом сетевое подключение должны быть строго Private. Запускаем коммандами

Enable-PSRemoting -Force
Set-Item wsman:\localhost\client\trustedhosts *
Restart-Service WinRM

проверям
Test-WsMan 192.168.1.218
Заходим на линукс машине командой
Enter-Pssession -computername 192.168.1.218 -credential USER
И не работает, ошибка

Enter-Pssession : MI_RESULT_ACCESS_DENIED
At line:1 char:1
+ Enter-Pssession -computername 192.168.1.218 -credential USER
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (192.168.1.218:String) [Enter-PSSession], PSInvalidOperationException
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed

И ни у кого не работает… это к вопрому о кросплотформенности! На другом виндовс, кстати проверил, работает, только там надо теже команды что на втором выполнить перед тем как подключаться!

Надежды мало, но может все таки powershell хорош для автоматизации управления виндовс сервер(это проверять не буду) и для автоматизации чего-нибудь на локальных машинах, это проверю!

По мотивам статьи Запускаем Linux через Windows Subsystem for Linux с примерами! пытаюсь сделать отправку сообщения о низком уровне картриджа на сетевом принтере!

Ищем на сайте www.powershellgallery.com по слову SNMP протокол по которому общаются сетевые устройства. Есть, даже написано как ставить
Install-Module -Name SNMP
вызываем модуль, перед этим отключив защиту от вызова модулей
set-executionpolicy remotesigned
и ставим
import-module snmp
смотрим хелп
get-help snmp
маловато только список команд, может по командам будет что-то
get-help get-snmpdata -full
Очень короткое описание… Особенно учитель по Powershell восхищался что для каждой команды есть примеры — тут нет!

Исполняем команду
get-snmpdata -ip 192.168.1.2 -oid 1.3.6.1.2.1.43.11.1.1.9.1.1 -version v2 -community public
вылезает

OID                          Data
---                          ----
.1.3.6.1.2.1.43.11.1.1.9.1.1 110

Теперь время уйти в другое окно, окно для удобного редактирования, без окон никак
в консоли пишем
ise
тут и буду дальше сидеть

Теперь пишу скрипт который будет брать значение 110 и присваивать его переменной pagesleft

get-snmpdata -ip 192.168.1.2 -oid 1.3.6.1.2.1.43.11.1.1.9.1.1 -version v2 -community public | select data -outvariable pagesleft
Write-Output "data is:"
$pagesleft 

Вроде бы работает но расстраивает:

1. Не удалось написать в одну строчку data is 110 — неудалось и все — write-host пробовал тоже
2. Чтобы в вывводе оставить только цифру надо это делать через конец добавить -outvariable
3. Если исполнение скрипта обрывается на середине, а после этого есть переменные то они все равно обработаются со значением последнего успешного запуска!!!!!!!!!!!!!!!

Подумал пару часиков, кое что понял по пунктам выше

1-2. В Powershell нельзя простыми и понятными командами обработать любой вывод выхватив только нужное слово или цифорку. Максимум можно выхватить нужный столбец и храниться он в переменной будет как {столбец|строка}. Поэтому нельзя рассчитывать что в переменной будет хранится только то что нужно, там еще будет и имя столбца и пр. Поэтому выше надо было цифорку запрашивать так $pagesleft.data
3. ISE, несмотря на то что пишет код в файл, просто кидает в консоль Powershell команды построчно, а переменные они разок объявлены так и хранятся в сессии этого Powershell. Поэтому если половина команд не работает то конечный результат будет таким как последний раз был назначен в течении этой сессии… по моему это самое чудовищное!

Ну ладно, теперь вывожу проценты тонера в картридже

get-snmpdata -ip 192.168.1.2 -oid 1.3.6.1.2.1.43.11.1.1.9.1.1 -version v2 -community public | select data -outvariable pagesleft | out-null
get-snmpdata -ip 192.168.1.2 -oid 1.3.6.1.2.1.43.11.1.1.8.1.1 -version v2 -community public | select data -outvariable pagestotal | out-null
$tonerleft=([int]$pagesleft.Data*100)/[int]$pagestotal.data
Write-host "Cartridge toner is:" $tonerleft"%" 

Выводы первых команды скрываются, вполне по линуксовому посылаются в нуль. Потом математика, нельзя просто так взять цифорку, не сказав powershell что это цифорка поэтому [int] — целая небольшая цифорка. Кто-то еще и округляет все, хотя я не просил…

но работает получаю

PS C:\Windows\system32> C:\Users\User\Documents\first.ps1
Cartridge toner is: 11%

Теперь команда для отсылки писем, она уже есть так что сразу код

get-snmpdata -ip 192.168.1.2 -oid 1.3.6.1.2.1.43.11.1.1.9.1.1 -version v2 -community public | select data -outvariable pagesleft | out-null
get-snmpdata -ip 192.168.1.2 -oid 1.3.6.1.2.1.43.11.1.1.8.1.1 -version v2 -community public | select data -outvariable pagestotal | out-null
$tonerleft=([int]$pagesleft.Data*100)/[int]$pagestotal.data
If ($tonerleft -lt 25) {
$From = "mymail@gmail.com"
$To = "hismail@gmail.com"
$Subject = "Low toner"
$Body = "Hi
Toner is low, only $tonerleft%
Buy a new one!"
$SMTPServer = "smtp.gmail.com"
$secpasswd = ConvertTo-SecureString -string "pAssVV0r1O" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential $From, $secpasswd
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $cred 
}

Тут все более менее. Только вот нельзя просто так вставить пароль. И хотя в команде говорит UseSSL порт надо ставить для TLS тот что у Gmail!

Теперь идем в свой gmail аккаунт myaccount.google.com/security и в Безопаность включаем Ненадежные приложения, у которых есть доступ к аккаунту

Запускаем работает!!!

Попытаемся засунуть этот скрип в планировщик
Попытаемся потому что это как бы не предполагалось и плохо продумано — а как же иначе если ты Майкрософт и делаешь язык для автоматизации то за чем думать о планировщике задач — пальцем тыкайте каждый раз!

Работать будет только от администратора
При первом запуске из планировщика, надо пару раз нажать Y чтобы установить модуль постоянно этого делать не надо будет… после одной перезагрузки точно нет
Если snmp не срабатывает, то письмо вам все равно придет с пустыми процентами, ну не останавливать же из-за ошибки весь скрипт

install-module -name snmp
import-module snmp
get-snmpdata -ip 192.168.1.2 -oid 1.3.6.1.2.1.43.11.1.1.9.1.1 -version v2 -community public | select data -outvariable pagesleft | out-null
get-snmpdata -ip 192.168.1.2 -oid 1.3.6.1.2.1.43.11.1.1.8.1.1 -version v2 -community public | select data -outvariable pagestotal | out-null
$tonerleft=([int]$pagesleft.Data*100)/[int]$pagestotal.data
If ($tonerleft -lt 25) {
$From = "mymail@gmail.com"
$To = "hismail@gmail.com"
$Subject = "Low toner"
$Body = "Hi
Toner is low, only $tonerleft%
Buy a new one!"
$SMTPServer = "smtp.gmail.com"
$secpasswd = ConvertTo-SecureString -string "pAs$VV0r1O" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential $From, $secpasswd
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $cred 
}

Тут добавлены две строки устанавливающие модуль! Настройки такие



На последнем скрине текст такой -ExecutionPolicy bypass C:\Users\User\Documents\first.ps1

Тут кстати майкрософт приапдейтела новый глюк, уверен 30 дней назад его не было. Настройки все чтобы запускать от админа — спросит пароль от админа, но не примет скажет неправильный пользователь! Чтобы приняло надо к имени админа приписать руками хостнейм компутера!

Powershell — мне непонравился, сплошная боль и мучения и это теперь совсем ни к чему когда есть Windows Subsystem for Linux

UPD: Делаем HTML страницу со всеми фотками, как до этого в WSL
Ресайзить картинки не буду, потому что не чем. В отличии от Linux где из скрипта можно обратится к куче программ, которые рассчитаны на работу в консоле и которые уже лет 20 продуктивно работают, в Powershell ничего этого нет. Есть модуль для ресайза картинок в галлерее, какой то студент его написал и видимо он работал только у него и только до момента получения зачета.

Сначала получим список файлов, создатели powershell шутьканули и теперь говорят что у нас такая же команда как в Linux и действительно:
ls
работет
ls *.jpg
работает
ls *.jpg > file.txt
работет
ls *.jpg| awk '{printf "file:"$1"\n"}' > file.txt
шутка линуксойда

Конечно ls это только ссылка на нативную комманду Get-ChildItem о пальцах никто не думал, сокрашать не стали, дети у них файлы ха!

Но за похожестью кроится и чудовишное отличие: если в линукс вывод команды — конвейр — pipe работает так
— держи первую строчку делай с ней что хочешь, держи дальше и тд
то в powershell это работает так
— на все что есть

ЧУДОВИЩНО!!! Надо отдельно говорить чтобы все было по человечский по линуксовому
перевод на повершеловский этой команды
ls *.jpg| awk '{printf "file:"$1"\n"}' > file.txt
будет
New-Item ./foto.txt -type file -force
Get-ChildItem *.jpg | ForEach-Object -Process {Add-Content ./file.txt -value ('file:'+$_.Name)}

в две строки, потому что сначала надо пересоздать файл чтобы очистить…в линуксе это делает >

И вот весь код , который создает папку web копирует туда фотки и делает там index.html который открывает все фотки

New-Item -ItemType Directory -Force -Path ./web, ./web/mini
Get-ChildItem *.jpg | Copy-Item  -Destination ./web
New-Item ./web/foto.html -type file -force -value "<html>`n"
Get-ChildItem *.jpg -path ./web | ForEach-Object -Process {Add-Content ./web/foto.html -value ('<img src=./'+($_.Name)+'><img><br>')}
Add-Content ./web/foto.html -value '</html>'

Теперь кладем его в папку где фотки .jpg нажимаем правой мышкой выбираем Run with Powershell при первом запуске появится окно где надо согласиться с исключением из правил безопасности чтобы запустить это скрипт и он сработает!


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *