Jump to content

Powershell command in autoit


hemichallenger
 Share

Recommended Posts

 

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

@hemichallenger 

In order to get this running you need to use the .NET CLR.au3 Udf from here :

Like this :

#AutoIt3Wrapper_UseX64=y
#include "..\Includes\CLR.Au3"
#include <FileConstants.au3>

; *****************************************************
; PARAMETERS : (Output mode )
; OUTPUT : 0 = Console, 1 = GRID, 2 = Printer, 3 = File, , 4 = Null
; *****************************************************

_Run_PSHost_Script('Get-Process -ComputerName "." | select -Property * | where name -like Name* ',3)

Func _Run_PSHost_Script($PSScript, $iOutput = 0)
    Local $oAssembly = _CLR_LoadLibrary("System.Management.Automation")
    ConsoleWrite("!$oAssembly: " & IsObj($oAssembly) & @CRLF)

    ; Create Object
    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.Management.Automation.PowerShell", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oActivatorType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oActivatorType) & @TAB & @CRLF)

    ; Create Object
    Local $pObjectPS = 0
    $oActivatorType.InvokeMember_3("Create", 0x158, 0, 0, 0, $pObjectPS)
    ConsoleWrite("IsObject: " & IsObj($pObjectPS) & @TAB & "$pObject: " & ObjName($pObjectPS) & @CRLF)

; <<<<<<<<<<<<<<<<<<< PS COMMAND HERE >>>>>>>>>>>>>>>>>>>>

    $pObjectPS.AddScript($PSScript) ; Add Script here

; <<<<<<<<<<<<<<<<<<< Output >>>>>>>>>>>>>>>>>>>>
        Switch $iOutput
            Case 0
;~              $pObjectPS.AddCommand("Out-Host")
;~              $pObjectPS.AddCommand("Out-String")
;~              $pObjectPS.AddCommand("Write-Host")
                Msgbox(16,"Error","This Output method '0' is not working yet :-( " & @CRLF & "choose another one")
                Exit
            Case 1
                $pObjectPS.AddCommand("Out-GridView")

            Case 2
                $pObjectPS.AddCommand("Out-Printer")
            Case 3
                $pObjectPS.AddCommand("Out-File")
                    $sFile = @DesktopDir & "\PShost.txt"
                    ConsoleWrite("> " & $sFile & @CRLF)
                $pObjectPS.AddArgument($sFile)
            Case 4
                $pObjectPS.AddCommand("Out-Null")
            Case Else
                MsgBox(0,"PSHost","Wrong Output Choice ?")
        EndSwitch

    $objAsync = $pObjectPS.BeginInvoke()
    ConsoleWrite("$objAsync " & IsObj($objAsync & @TAB & "$pObject: " & ObjName($objAsync) ) & @CRLF)

    While $objAsync.IsCompleted = False
;~          ConsoleWrite($objAsync.IsCompleted & @CRLF)
        ContinueLoop
    WEnd

    $objPsCollection = $pObjectPS.EndInvoke($objAsync)


    Switch $iOutput
            Case 0
;~              ConsoleWrite( $objPsCollection & @CRLF)
                MsgBox(16,"PSHost","Output To Console is not working yet :-( ?" & @CRLF &  @CRLF & " Best make a different OUTPUT option.")
            Case 1
                Sleep(10000)
;~              WinWaitClose("")
            Case 3
                MsgBox(0,"PSHost","File Output Ready on Desktop.")
        EndSwitch
EndFunc

 

Enjoy!

Edited by ptrex
Link to comment
Share on other sites

@ptrex

what are the advantages to object style over just sending the command as a parameter to a powershell executable call?  Just speed?

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Thank you guys for your assistance. @iamtheky I used your method and used run(@comspec) to run powershell. Was the easiest way to run the commands.

$name = "task" & "*"
$computer = @ComputerName
$PS = 'powershell -command "&{Get-Process -computername ' & $computer & ' | where processname -like ' & $name & '}" '
$Results = Run(@ComSpec & " /c " & $PS, "", @SW_hide , $stdout_child)

Link to comment
Share on other sites

Advantages using the CLR UDF are mainly no depencies needed.

When compiling your Au3 scripts you can have everything in 1 EXE and it will be very portable to other machines...

When using the commandline you need to involve 2 dependencies

Quote

au3 -> cmd -> powershell.exe -|

au3 <- cmd <- powershell.exe -|

 

I have not compared speed between the 2 approaches though ... ?

 

Link to comment
Share on other sites

yours is dependent on the powershell framework being installed as well, it blows up on my hardened system that lacks the feature entirely.  I have not seen a scenario in which all the guts are there but the .exe is not.  Yours definitely kills in speed as the startup for powershell.exe is measured in seconds.

Where yours may do some serious work is If I can call the powershell object that resides in an offline image, might be able to game over some master images :)

and cmd isnt required for most of my ps scripts its just a cleaner template as some of my PS script examples perform tasks across multiple shells all brought back through stdout. 

 

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

"I have not seen a scenario in which all the guts are there but the .exe is not. "

Here are a few :

- Powershell on Windows AD Core Server

- Powershell on Windows 10 Iot Server

- ...

If you can find the PowerShell.exe on these server let us know :D

 

Link to comment
Share on other sites

Ah, Wasn’t thinking server flavors.  In prod on all my full 2016 boxes I use remote powershell so I can run things as admin without having to allow elevated accounts locally.

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Another issue I ran into using cmd powershell -command. The output sends out all the results in one-line in a edit box. But in a MsgBox it displays correct and multiple-lines. How do I get the same output as the message box in a edit box?

Example

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
#include <EditConstants.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 367, 266, 201, 222)
$output = GUICtrlCreateEdit("", 8, 16, 345, 201, BitOR($ES_UPPERCASE,$ES_AUTOVSCROLL,$ES_READONLY))
GUICtrlSetData(-1, "")
$Button1 = GUICtrlCreateButton("enter", 96, 224, 177, 33)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
  Case $Button1
   Example()
 EndSwitch
WEnd


Func Example()
  $cmd3 = 'powershell -command "&{Write-Host This is line 1 ' & _
 ' ; ' & 'Write-Host This is line 2}"'
 Local $iPID = Run(@ComSpec & ' /c"' & $cmd3 & '"', @SystemDir, @SW_HIDE, $STDOUT_CHILD)
 ProcessWaitClose($iPID)
 Local $sOutput = StdoutRead($iPID)
 MsgBox(0,"",$sOutput)
 GUICtrlSetData($output,$sOutput)
EndFunc

Link to comment
Share on other sites

maybe an  " `r `n" in the powershell  cmd a la:

powershell -command Write-Host "This is line 1 `r`n This is line 2"

 

https://blogs.technet.microsoft.com/heyscriptingguy/2014/09/07/powertip-new-lines-with-powershell/

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

  • Moderators

This is how I am doing it, sometimes get duplicate lines but otherwise seems to work ok:

Local $sPSScript = @ScriptDir & "\PassThrough.ps1"
Local $sText = "", $sSTDOUT = ""
Local $sCMD = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command . '" & $sPSScript & "'"
Local $pid = Run($sCMD, @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
    StdinWrite($pid)

    While 1
        $sOutput = StdoutRead($pid)
            If @error Then ExitLoop
        If $sOutput <> "" Then _GUICtrlEdit_AppendText($editProgress, $sOutput)
    WEnd

 

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

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...