Faire semblant d'écrire en C #, mais uniquement en Powershell



Powershell est une API pratique basée sur .net. Powershell permet aux utilisateurs d'écrire des scripts sans se soucier de la programmation, tout en obtenant des résultats similaires. Ce qui se passe au KDVP, l'auteur expliquera plus loin dans le texte. Maintenant, nous devons de toute urgence prétendre que nous programmons en C #.



TL; DR: Postman n'est pas nécessaire si Powershell est disponible. Mais il faut d'abord partir de loin.



Faire un cours simple



J'ai entendu dire que les programmeurs sympas font tout à travers les classes et leurs méthodes.

Puisque PowerShell le permet, laissez-moi vous montrer comment vous pouvez ajouter 1 + 1 tout en faisant semblant de programmer.



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


Voici notre classe ClassName et sa méthode Sum. Une instance d'une classe peut être appelée exactement de la même manière que dans les vrais langages de programmation.



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


Nous créons une nouvelle instance de la classe et appelons la méthode, tout est simple.



Y a-t-il un vide dans Powershell



Lors de l'écriture de scripts complexes, la même question s'est posée de l'auteur. Comment faire une fonction qui sera nulle?



Ils disent que vous pouvez faire ceci:



Get-Date | Out-Null


Cependant, | Out-Null supprime également tous les Verbose, ErrorAction et ne fonctionne pas avec Invoke-Command.



Si vous avez besoin d'une fonction avec [Void] - créez une nouvelle classe, il n'y a pas d'autre issue.



class ClassName {
 
    # 
    [void] Start () {
        #       .
        $q = [ClassName]::new()
        $q.GetDate()
    }
 
    #    
    [void] GetDate () {
        #        .Net
	  # ,   
        $Result = [DateTime]::UtcNow.ToString()
        Write-Host $Result
    }
}


Il est impossible de rendre une méthode privée dans une classe ou d'appeler l'une des méthodes de classe dans la même classe dans PowerShell, vous devez donc sculpter de tels appels.

Un constructeur de classe a été ajouté à l'exemple pour comprendre les limitations du langage, et un tel code ne doit généralement pas être écrit.



C'est ainsi que nous avons réussi à éviter de nous noyer Verbose, tout en créant une fonction avec Void.



Liste des méthodes de classe



Disons que vous devez créer un programme, peut-être même dans une langue que vous ne connaissez pas. Vous savez qu'il existe une classe, mais ses méthodes sont mal documentées.



Vous pouvez lister toutes les méthodes de la classe d'intérêt comme suit:



# ,   
$Love = [ClassName]::new()
 
#        .
foreach ($i in $Love | Get-Member -MemberType Method | Select-Object name) {
    [array]$array += $i.Name
}
 
#  ,  .
$Array | ForEach-Object {
    $Love.$_()
}


Nous envoyons des requêtes HTTP avec un script (nous justifions KDPV)



Avec les classes, nous pouvons représenter des données et convertir ces données en différents formats. Par exemple, nous devons envoyer une requête POST à ​​un site Web au format JSON.



Tout d'abord, nous créons un modèle de données et remplissons les données dans une nouvelle instance.



#      
class DataModel {
    $Data
    $TimeStamp
}
 
#  
$i = [DataModel]::new()
 
# 
$i.Data = "My Message in string"
$i.TimeStamp = Get-Date


Voici à quoi ressemble l'instance de classe après le remplissage:



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


Ensuite, cette instance peut être convertie en XML ou JSON ou même en une requête SQL. Attardons-nous sur JSON:



#   JSON
$Request = $i | ConvertTo-Json


Voici à quoi ressemble le JSON après l'avoir converti:



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


Et nous envoyons:



# JSON
Invoke-WebRequest localhost -Body $Request -Method Post -UseBasicParsing


Si vous devez envoyer le même fichier JSON 24h / 24 et 7j / 7, vous pouvez l'enregistrer en tant que fichier et l'envoyer à partir du fichier. Par exemple, prenons ce même $ Request.



#     JSON  
$Request | Set-Content C:\Users\User\Desktop\YourRequest.json
 
#     JSON
Invoke-WebRequest localhost -Body (Get-Content C:\Users\User\Desktop\YourRequest.json) -Method Post -UseBasicParsing


Nous recevons des requêtes HTTP avec un script (nous justifions KDPV 2)



L'auteur déteste Postman, pourquoi quelqu'un aurait-il besoin de Postman alors qu'il a des mains et PowerShell? (L'auteur est partisan de ce programme et son aversion n'est justifiée par rien.)

Nous ferons notre alternative en utilisant System.Net.HttpListener, c'est-à-dire que nous allons maintenant démarrer un vrai serveur Web à partir d'un script.



#   
$http = [System.Net.HttpListener]::new()
 
# HTTP .     
$http.Prefixes.Add("http:/localhost/")
$http.Prefixes.Add("http://127.0.0.1/")
 
#  
$http.Start()
 
 
$http.Close()


C'est ainsi que commence la classe.



Une instance de la classe a été créée et son processus démarré, nous pouvons écouter sa sortie. La sortie est présentée sous la forme System.Net.HttpListener.GetContext. Dans cet exemple, nous acceptons et convertissons uniquement une requête 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
           
        }
    }
} 


Script prêt



Avec ce script, vous pouvez accepter les demandes:



#   
$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
}


Les données seront automatiquement converties à partir de JSON et envoyées au terminal.



L'auteur espère que vous jetez Postman, ainsi que GIT avec une interface graphique.






All Articles