GoPowerShellPSHTML

Build web app using PowerShell PSHTML module in Go Lang!

 

Off late I became a great fan of web frameworks. I received positive responses from many PowerShell folks across the globe. So, I tried my best to assist all who reached me to get assistance in node.js, PowerShell and Pug in their internal works.

I worked on few real time projects using node.js and PowerShell which are listed below

  1. HRM – Interface automation.
  2. AD Password Reset tool.
  3. CMS Automation

Through which I learnt few web concepts concepts and gained experience in HTML, CSS and JS – During this travel I blogged about Polaris, PSHTML, Node.js, PUG etc – Irwin and Dexter Posh shared their comments….

Irwin – Though node is growing on me – Go is very interesting and worth trying!

Deepak – Go is helpful for me to work with terraform. Its faster, powerful than expected…

Yes, with no doubt I gave a try – At first I faced difficulties to adapt which is quite common for a beginner. I realized that I am comparing Go with other languages I worked with ?.  If you are new to Go like me then GO from here

  1. Go – Tutorials Point
  2. Go – YouTube Videos

Let me show the simple steps which I carried out to build my first web server using Go. Yes, as you all guessed I used PSHTML in Go as my html template – In node.js child_process or node-powershell (in-built and a wrapper respectively) are used to call external executable – In Go, we use os/exec – I am skipping to use the PowerShell wrapper for now.

Let us first do hello world – Yes, this is not a programmers choice – This exercise is mandatory to know if all set to good 🙂

 


package main
import (
    "fmt"
)
func main() {
    fmt.Printf("Hello World!")
}

If it fails, stop and rework on Go configuration. So, let me show one more example to print date from PowerShell. Yes, here we call powershell.exe inside the Go and retrieve the output.


package main
import (
    "fmt"
    "os/exec"
    "log"
)
func main() {
    out,err := exec.Command("powershell.exe","-file" , "C:\\Projects\\iGoLang\\date.ps1").Output()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("The Date is %s",out)
}

We are all set good to host our new web server and for that we use additional packages like illustrated below


import (
  "html/template"
  "log"
  "net/http"
  "time"
  "os/exec"
  "bytes"
)

Now, with no wait let me show you the full code.


package main

import (
  "log"
  "net/http"
  "os/exec"
  "bytes"
  "fmt"
)

func main() {
    http.HandleFunc("/", HomePage)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func HomePage(w http.ResponseWriter, r *http.Request){
    out,err := exec.Command("powershell.exe","-file" , "C:\\Projects\\iGoLang\\pshtml.ps1").Output()
    if err != nil {
        log.Fatal(err)
    }
    psHTML := bytes.NewBuffer(out).String()
    url := r.FormValue("url")
    if url == "" {
        w.Header().Set("Content-Type", "text/html; charset=utf-8")
        fmt.Fprint(w, psHTML)
        return
    }
    key := "Placeholder"
    fmt.Fprintf(w, "http://localhost:8080/%s", key)
}

Here, the psHTML variable contains the output of PS1 which is our PowerShell way of rendering HTML – Go calls the PS1 using the os/exec and triggers the execution by exec.Command – The output will be a bytes array so I converted to string.


html -Content {
    head -Content {
        Title -Content "iCMS | Tools"
        Link -href "https://cdn.metroui.org.ua/v4/css/metro-all.min.css" -rel "stylesheet"
        Link -href "https://cdn.metroui.org.ua/v4/css/metro.min.css" -rel "stylesheet"
        Link -href "https://cdn.metroui.org.ua/v4/css/metro-colors.min.css" -rel "stylesheet"
        Link -href "https://cdn.metroui.org.ua/v4/css/metro-rtl.min.css" -rel "stylesheet"
        Link -href "https://cdn.metroui.org.ua/v4/css/metro-icons.min.css" -rel "stylesheet"
        script -src "https://code.jquery.com/jquery-3.3.1.min.js"
        script -src "https://cdn.metroui.org.ua/v4/js/metro.min.js"
    }
    body -content {
        $UserInfo = Get-Content 'C:\Projects\iGoLang\user.json' | ConvertFrom-Json
        h1 -content "Self Request" -Class "text-center"
        (1..2).ForEach( {br})
        Form -action "/response" -method "post" -target "_blank" -Content {
            Div -Class "form-group" -Content {
                input -type 'text' -name "firstname" -value $UserInfo.firstname
                br
                input -type 'text' -name "lastname" -value $UserInfo.lastname
                br
                input -type "text" -name "emailaddress" -value $UserInfo.emailaddress
                br
                input -type 'text' -name "phonenumber" -value $UserInfo.phonenumber
                br
                button -Class "button mif-checkmark bg-darkBlue" -Content {
                    "Submit to Register"
                } -Attributes @{
                    'style' = 'font-family:Segoe UI'
                }
            }
        }        
    }
}

This is just a start and to test if I can get PS on GO – Very well wrapper can be used but I am not sure about the limitation. The PSHTML module loading time is high and the issue is logged and tracked here.

Leave a Reply

Your e-mail address will not be published. Required fields are marked *