Русский
Русский
English
Статистика
Реклама

Притворяемся что пишем на C, но только на Powershell


Powershell удобная API построенная на .net. Powershell позволяет пользователям писать скрипты, не упираясь в программирование, при этом получая схожие результаты. Что происходит на КДВП, автор объяснит позже по тексту. Сейчас нам срочно нужно притвориться, что мы программируем на C#.

TL;DR: Postman не нужен, если есть Powershell. Но сперва нужно зайти издалека.

Делаем простой класс


Автор слышал, что крутые программисты делают все через классы и их методы.
Так как PowerShell это позволяет, давайте автор покажет, как можно сложить 1 + 1 притворившись, что мы программируем.

class ClassName {     [string] Sum ($A, $B) {               $Result = $A + $B        return $Result    }}

Вот наш класс ClassName и его метод Start. Экземпляр класса можно вызвать ровно так же, как в настоящих языках программирования.

$NewClass = [ClassName]::new()$NewClass.Sum(1, 1)

Создаем новый экземпляр класса и вызываем метод, всё просто.

Есть ли Void в Powershell


При написании сложных скриптов этот же вопрос вставал у автора. Как сделать функцию, которая будет Void?

Говорят, что можно сделать так:

Get-Date | Out-Null

Однако, | Out-Null так же глушит весь Verbose, ErrorAction и не работает с Invoke-Command.

Если вам нужна функция с [Void] делайте новый класс, другого выхода нет.

class ClassName {     #Конструктов класса    [void] Start () {        #Создаем экземпляр класса прямо внутри этого же класса.        $q = [ClassName]::new()        $q.GetDate()    }     #Своего рода метод внутри класса    [void] GetDate () {        #А вот тут вызываем еще один метод из .Net  #Просто так, потому что можем        $Result = [DateTime]::UtcNow.ToString()        Write-Host $Result    }}

Сделать метод приватным внутри одного класса, или вызвать один из методов класса внутри этого же класса в PowerShell невозможно, поэтому приходится лепить такие вот вызовы.
Конструктор класса был добавлен в пример для понимания ограничений языка и такой код писать в целом не стоит.

Вот так мы добились того, что не заглушили Verbose, при этом сделали функцию с Void.

Список методов класса


Скажем, вам нужно сделать программу, возможно, даже на языке, который вы не знаете. Вы знаете, что есть какой-то класс, но методы его плохо документированы.

Перечислить все методы интересующего класса можно так:

#Делаем любовь, а не класс$Love = [ClassName]::new() #Выбираем члены интересующего нас класса и записываем в массив.foreach ($i in $Love | Get-Member -MemberType Method | Select-Object name) {    [array]$array += $i.Name} #Вызываем члены класса, если нужно.$Array | ForEach-Object {    $Love.$_()}

Отправляем HTTP запросы скриптом (оправдываем КДПВ)


Классами мы можем представлять данные и эти данные конвертировать в разные форматы. К примеру, нам нужно отправить POST запрос на веб сайт в формате JSON.

Сначала мы делаем модель данных и заполним данные в новый экземпляр.

#В качестве модели данных делаем новый классclass DataModel {    $Data    $TimeStamp} #Создаем экземляр класса$i = [DataModel]::new() #Заполняем данные$i.Data = "My Message in string"$i.TimeStamp = Get-Date

Так выглядит экземпляр класса после заполнения:

PS C:\> $i Data                 TimeStamp----                 ---------My Message in string 30.07.2020 5:51:56

Потом этот экземпляр можно конвертировать в XML или JSON или даже SQL запрос. Остановимся на JSON:

#Конвертируем данные в JSON$Request = $i | ConvertTo-Json

Так выглядит JSON после его конвертации:

PS C:\> $Request{  "Data": "My Message in string",  "TimeStamp": "2020-07-30T05:51:56.6588729+03:00"}

И отправляем:

#Отправляем JSONInvoke-WebRequest localhost -Body $Request -Method Post -UseBasicParsing

В случае если нужно отправлять один и тот же JSON файл 24/7, можно сохранить его как файл и отправлять уже из файла. К примеру, возьмем этот же самый $Request.

#Сохраняем данные конвертированные ранее в JSON в файл$Request | Set-Content C:\Users\User\Desktop\YourRequest.json #Отправляем ранее сохраненный в файл JSONInvoke-WebRequest localhost -Body (Get-Content C:\Users\User\Desktop\YourRequest.json) -Method Post -UseBasicParsing

Получаем HTTP запросы скриптом (оправдываем КДПВ 2)


Автор терпеть не может Postman, зачем кому-либо нужен Postman, когда есть руки и PowerShell? (Автор предвзято относится к этой программе и его нелюбовь ничем не обоснована.)
Делать свою альтернативу мы будем это с помощью System.Net.HttpListener, то есть мы сейчас запустим настоящий веб сервер из скрипта.

#Создаем новый экземпляр класса$http = [System.Net.HttpListener]::new() #Добавляем HTTP префиксы. Их может быть сколько угодно$http.Prefixes.Add("http:/localhost/")$http.Prefixes.Add("http://127.0.0.1/") #Запускаем хттп листенер$http.Start()  $http.Close()

Так проходит запуск класса.

Экземпляр класса был создан и его процесс запустился, мы можем слушать от него вывод. Вывод представлен как System.Net.HttpListener.GetContext. В это примере мы принимаем и конвертируем только POST запрос.

while ($http.IsListening) {     #GetContext нужен для получения сырых данных из HttpListener    $context = $http.GetContext()     #Определяем тип запроса с помощью Request.HttpMethod     if ($context.Request.HttpMethod -eq 'POST') {         #Читаем сырые данные из GetContext        #Для каждого отдельного запроса создаем свой конвейер        [System.IO.StreamReader]::new($context.Request.InputStream).ReadToEnd() | ForEach-Object {                        #С помощью System.Web.HttpUtility делаем urlDecore, иначе кириллица превращается в руны            $DecodedContent = [System.Web.HttpUtility]::UrlDecode($_)             #Конвертируем прилетевшие данные в нужный нам формат            $ConvertedForm = $DecodedContent | ConvertFrom-Json -ErrorAction SilentlyContinue             #Cконвертированные данные отображаем таблицой            $ConvertedForm | Format-Table                   }    }} 

Готовый скрипт


С помощью этого скрипта можно принимать запросы:

#Создаем новый экземпляр класса$http = [System.Net.HttpListener]::new() #Добавляем HTTP префиксы. Их может быть сколько угодно$http.Prefixes.Add("http://localhost/")$http.Prefixes.Add("http://127.0.0.1/")#Запускаем веб листенер$http.Start() if ($http.IsListening) {    Write-Host "Скрипт запущен"} while ($http.IsListening) {     #GetContext нужен для получения сырых данных из HttpListener    $context = $http.GetContext()     #Определяем тип запроса с помощью Request.HttpMethod     if ($context.Request.HttpMethod -eq 'POST') {         #Читаем сырые данные из GetContext        #Для каждого отдельного запроса создаем свой конвейер        [System.IO.StreamReader]::new($context.Request.InputStream).ReadToEnd() | ForEach-Object {                        #С помощью System.Web.HttpUtility делаем urlDecore, иначе кириллица превращается в руны            $DecodedContent = [System.Web.HttpUtility]::UrlDecode($_)             #Конвертируем прилетевшие данные в нужный нам формат            $ConvertedForm = $DecodedContent | ConvertFrom-Json -ErrorAction SilentlyContinue             #Cконвертированные данные отображаем таблицей            $ConvertedForm | Format-Table                   }         #Отвечаем клиенту 200 OK и закрываем стрим.        $context.Response.Headers.Add("Content-Type", "text/plain")        $context.Response.StatusCode = 200        $ResponseBuffer = [System.Text.Encoding]::UTF8.GetBytes("")        $context.Response.ContentLength64 = $ResponseBuffer.Length        $context.Response.OutputStream.Write($ResponseBuffer, 0, $ResponseBuffer.Length)        $context.Response.Close()     }    #Cконвертированные данные отображаем таблицей    $http.Close()    break}


Данные будут автоматичеки конвертироваться из JSON и выводиться в терминал.

Автор надеется, что вы выбросите Postman, так же, как и GIT с GUI.

Источник: habr.com
К списку статей
Опубликовано: 05.08.2020 12:20:05
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании ruvds.com

Программирование

Powershell

Лайфхаки для гиков

Лайфхак

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru