Jump to content

Output powershell script in console


Recommended Posts

Hello everybody.

Happy New Year ! May the AutoIt force be with you. 🙂

 

I created a function _RunPSHost() to launch and get output from Powershell commands/scripts.

As you can see with my code, it works with powershell commands but not with scripts.

Could you help me ?

 

#include <AutoItConstants.au3>
#include <FileConstants.au3>
#include <WinAPIConv.au3>

Global $g_iPSHost = 0
Global $g_sFilePS = @ScriptDir & '\TEST.ps1'

Test()

Func Test()
    Local $hFile = FileOpen($g_sFilePS, $FO_OVERWRITE)
    FileWriteLine($hFile, 'Write-Host test file')
    FileWriteLine($hFile, 'Write-Host END_OF_OUTPUT')
    FileClose($hFile)

    $g_iPSHost = Run('powershell.exe -ExecutionPolicy Bypass -NoProfile -command - ', @SystemDir, @SW_HIDE, BitOR($STDIN_CHILD, $STDERR_CHILD, $STDOUT_CHILD))

    _RunPSHost($g_iPSHost, 'Write-Host test cmd', False, True)
    _RunPSHost($g_iPSHost, '. "' & $g_sFilePS & '"', True, True)
EndFunc   ;==>Test

Func _RunPSHost($iPSHost, $sPSCmd, $bScript = False, $bVerbose = False)
    Local $sOutput = '', $sError = ''

    If $bScript = False Then $sPSCmd &= '; Write-Host END_OF_OUTPUT' & @CRLF

    If $bVerbose Then ConsoleWrite(@CRLF & '================================================== BEGIN RunPSHost ==================================================' & @CRLF)
    If $bVerbose Then ConsoleWrite('Commande : ' & $sPSCmd & @CRLF)
    StdinWrite($iPSHost, $sPSCmd)
;~  If $bScript Then StdinWrite($iPSHost, @CRLF & 'Write-Host END_OF_OUTPUT')

    If $bScript = False Then
        While 1 ; detects when data starts to stream in and then exits the loop
            $sOutput &= StdoutRead($iPSHost)
            If @extended > 0 Then ExitLoop
            Sleep(1000)
        WEnd
    EndIf

    If $bVerbose Then ConsoleWrite('Waiting text "END_OF_OUTPUT"' & @CRLF)
    While 1 ; data has begun to stream, wait text "END_OF_OUTPUT" which tells first command has completed
        $sError &= StderrRead($iPSHost)
        $sOutput &= StdoutRead($iPSHost)
        If $bVerbose And $sOutput <> '' Then ConsoleWrite($sOutput & @CRLF)
        If StringInStr($sOutput, 'END_OF_OUTPUT') Then ExitLoop
        Sleep(1000)
    WEnd
    If $bVerbose Then ConsoleWrite('Found text "END_OF_OUTPUT"' & @CRLF)

    If $sError <> '' Then
;~      ConsoleWrite($sError & @CRLF)
        $sError = _WinAPI_OemToChar($sError)
        $sError = StringRegExpReplace($sError, '(?s)(.*?)Au caractère.*', '$1')
        $sError = StringRegExpReplace($sError, '\R', ' ')
        Return SetError(1, 0, $sError)
    EndIf

    $sOutput = StringRegExpReplace(_WinAPI_OemToChar($sOutput), '\R*END_OF_OUTPUT\R', '')
    ConsoleWrite($sOutput & @CRLF)
    If $bVerbose Then ConsoleWrite('==================================================   END RunPSHost ==================================================' & @CRLF)

    Return $sOutput
EndFunc   ;==>_RunPSHost

 

Link to comment
Share on other sites

Hi @MWIProd,

how your TEST.ps1 looks like? What exactly doesn't work properly?
How about to write your powershell scripts output to a file and read this?

Best regards
Sven

________________
Stay innovative!

Stay innovative!

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

Link to comment
Share on other sites

Hi @SOLVE-SMART,

 

TEST.ps1 is created in my au3script. 😉 

I prefer to read output from console. And I want understand why it doesn't work. 🙄

 

I omit to specify that I don't want launch another powershell instance to run PS script. I want to launch PS script(s) on the same PS instance.

If I use this code, it works. But this is not what I want to do.

$sCMD = "powershell.exe -file " & @ScriptDir & "\TEST.ps1"
$iPID = Run($sCMD, @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
...

 
Edited by MWIProd
Link to comment
Share on other sites

1 minute ago, MWIProd said:

Hi @SOLVE-SMART,

 

TEST.ps1 is created in my au3script. 😉 

I prefer to read output from console. And I want understand why it doesn't work. 🙄

 

I omit to specify that I don't want launch another powershell instance to run PS script. I want to launch PS script(s) on the same PS instance.

If I use this code, it works. But this is not what I want to do.

$sCMD = "powershell.exe -file " & @ScriptDir & "\TEST.ps1"
$iPID = Run($sCMD, @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
...

 

Understood 👍 . I will have another look.

Best regards
Sven

________________
Stay innovative!

Stay innovative!

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

Link to comment
Share on other sites

Hello.

Interesting idea, I picked it up for a task, that I had to solve anyway.

Maybe this sample code is giving you a start:

; *** Start added by AutoIt3Wrapper ***
#include <GUIConstantsEx.au3>
; *** End added by AutoIt3Wrapper ***
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Add_Constants=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; *** Start added by AutoIt3Wrapper ***
#include <AutoItConstants.au3>
; *** End added by AutoIt3Wrapper ***
#include <Date.au3>

$Output = ""
$OutputOld=$Output

$Gui_W = 600
$Gui_H = 900
$Ctrl_H = 20

$MyGUI = GUICreate("PS helper", $Gui_W, $Gui_H, 50, 50)
$Input = GUICtrlCreateInput("", 20, 20, $Gui_W - 40, $Ctrl_H)
Opt("Guicoordmode", 2) ; cell relative
$BtnGo = GUICtrlCreateButton("Send command", -1, 10)
Opt("Guicoordmode", 1) ; absolute
$Edit = GUICtrlCreateEdit($Output, 20, 80, $Gui_W - 40, $Gui_H - 100)
GUICtrlSetState($Edit, $GUI_DISABLE)
GUISetState()
WinSetOnTop($MyGUI, "", 1)


$PSPID = Run("powershell.exe", @TempDir, @SW_HIDE, $STDIN_CHILD +  $STDERR_MERGED)
AdlibRegister("UpdateOutput")


While ProcessExists($PSPID)
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $BtnGo
            $Line = GUICtrlRead($Input)
            StdinWrite($PSPID,$Line & @CRLF)
            GUICtrlSetData($Input,"")
    EndSwitch

WEnd

MsgBox(0, "Powershell PID vanished", "PID " & $PSPID & " no longer exists.",5)


Func UpdateOutput()
    $Output &= StdoutRead($PSPID)
    if $Output=$OutputOld Then
        ; nothing changed
    Else
        $OutputOld=$Output
        ClipPut($Output)
        ToolTip(_NowCalc() & @CRLF & $Output)
        GUICtrlSetData($Edit, $Output)
    EndIf
EndFunc   ;==>UpdateOutput

 

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to comment
Share on other sites

If I use :

FileWriteLine($hFile, 'Start-Transcript c:\temp\log.txt')
FileWriteLine($hFile, 'Write-Host test file')
FileWriteLine($hFile, 'Write-Host END_OF_OUTPUT')
FileWriteLine($hFile, 'Stop-Transcript')

I can see the output in log file :

test file
END_OF_OUTPUT

So the script TEST.ps1 is launched but the output is not sent to console. 😞

Link to comment
Share on other sites

Hey @MWIProd.  can you try replacing your "fileopen" command with this instead?

 

Local $hFile = FileOpen($g_sFilePS, 514)

This modification will create the powershell script using ANSI reading and writing mode.  I wrote a script once upon a time that would create powershell scripts using the contents of an edit box, but when I tried executing the script that was created, nothing would happen.  Using the above code fixed that for me.  Give it a shot.

Link to comment
Share on other sites

Hello @MattHiggs

It doesn't work.

This code is for AutoIt Forum members (help testing)

Local $hFile = FileOpen($g_sFilePS, $FO_OVERWRITE)
;~  Local $hFile = FileOpen($g_sFilePS, 514)
    FileWriteLine($hFile, 'Start-Transcript c:\temp\log.txt')
    FileWriteLine($hFile, 'Write-Host test file')
    FileWriteLine($hFile, 'Write-Host END_OF_OUTPUT')
    FileWriteLine($hFile, 'Stop-Transcript')
    FileClose($hFile)

In reality, my PS script is an external file (No BOM format). It doesn't work too.

Edited by MWIProd
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...