Pretende escribir en C #, pero solo en Powershell



Powershell es una API práctica construida en .net. Powershell permite a los usuarios escribir scripts sin preocuparse por la programación, mientras obtienen resultados similares. Lo que sucede en el KDVP, el autor lo explicará más adelante en el texto. Ahora necesitamos con urgencia fingir que estamos programando en C #.



TL; DR: Postman no es necesario si Powershell está disponible. Pero primero tienes que ir desde lejos.



Hacer una clase sencilla



He oído que los programadores geniales hacen todo a través de clases y sus métodos.

Dado que PowerShell lo permite, deje que el autor le muestre cómo puede agregar 1 + 1 mientras pretende programar.



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


Aquí está nuestra clase ClassName y su método Sum. Una instancia de una clase se puede llamar exactamente de la misma manera que en los lenguajes de programación reales.



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


Creamos una nueva instancia de la clase y llamamos al método, todo es simple.



¿Hay un vacío en Powershell?



Al escribir guiones complejos, la misma pregunta surgió del autor. ¿Cómo hago una función que será nula?



Dicen que puedes hacer esto:



Get-Date | Out-Null


Sin embargo, | Out-Null también suprime todo Verbose, ErrorAction y no funciona con Invoke-Command.



Si necesita una función con [Void], cree una nueva clase, no hay otra salida.



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


Es imposible convertir un método en privado dentro de una clase o llamar a uno de los métodos de clase dentro de la misma clase en PowerShell, por lo que debe esculpir dichas llamadas.

El constructor de la clase se agregó al ejemplo para comprender las limitaciones del lenguaje, y dicho código no debe escribirse en general.



Así es como logramos evitar ahogar a Verbose, mientras hacíamos una función con Void.



Lista de métodos de clase



Digamos que necesita hacer un programa, quizás incluso en un idioma que no conoce. Sabes que hay una clase, pero sus métodos están mal documentados.



Puede enumerar todos los métodos de la clase de interés de la siguiente manera:



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


Enviamos solicitudes HTTP con un script (justificamos KDPV)



Con las clases podemos representar datos y convertir estos datos en diferentes formatos. Por ejemplo, necesitamos enviar una solicitud POST a un sitio web en formato JSON.



Primero, creamos un modelo de datos y llenamos los datos en una nueva instancia.



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


Así es como se ve la instancia de la clase después del llenado:



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


Entonces esta instancia se puede convertir a XML o JSON o incluso a una consulta SQL. Detengámonos en JSON:



#   JSON
$Request = $i | ConvertTo-Json


Así es como se ve JSON después de convertirlo:



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


Y enviamos:



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


Si necesita enviar el mismo archivo JSON las 24 horas del día, los 7 días de la semana, puede guardarlo como un archivo y enviarlo desde el archivo. Por ejemplo, tomemos este mismo $ 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


Recibimos solicitudes HTTP con un script (justificamos KDPV 2)



El autor odia Postman, ¿por qué alguien necesitaría Postman cuando tiene manos y PowerShell? (El autor está predispuesto hacia este programa y su disgusto no está justificado por nada).

Haremos nuestra alternativa usando System.Net.HttpListener, es decir, ahora iniciaremos un servidor web real desde 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()


Así comienza la clase.



Se creó una instancia de la clase y se inició su proceso, podemos escuchar su salida. La salida se presenta como System.Net.HttpListener.GetContext. En este ejemplo, solo aceptamos y convertimos una solicitud 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
           
        }
    }
} 


Guión listo



Con este script, puede aceptar solicitudes:



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


Los datos se convertirán automáticamente de JSON y se enviarán al terminal.



El autor espera que elimine a Postman, así como a GIT con una GUI.






All Articles