Jump to content

StdoutRead a Powershell window.


Go to solution Solved by blckpythn,

Recommended Posts

I have a script that executes powershell commands to interact with Office 365(Microsoft hosted Exchange service).

I want to hide the powershell window and interpret the output silently, so that non-savvy users can reset passwords and such without having to learn powershell or understand its errors.

However, when I use:

Func RunCommand($commandtorun)
    $output = ""
    If WinExists("Administrator:") Then WinActivate("Administrator:")
    Send($commandtorun & "{ENTER}")
    While 1
        $output &= StdoutRead($pwshell)
        If @error Then ExitLoop
    WEnd
    MsgBox(0, "stdoutread", $output)
EndFunc   ;==>RunCommand

It doesn't exit the loop until I close the powershell window.(by design I believe)

Is there another way to return just a particular command's output?

Also, if I use $Stdin_child, the powershell window doesn't display its prompt for a command until I close my script.

Is that by design also?

Link to post
Share on other sites

How are you starting the powershell command window? The Run command allows you to read the StdIO streams, have you tried that?

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to post
Share on other sites

How are you starting the powershell command window? The Run command allows you to read the StdIO streams, have you tried that?

 

I'm starting it with the following and having trouble with the stdoutread command.

$pwshell = Run(@SystemDir & '\WindowsPowerShell\v1.0\powershell.exe  -NoExit -Command "Import-Module MSOnline"', "", @SW_SHOW, $STDERR_CHILD + $STDOUT_CHILD)

The issue with powershell not showing the prompt is when I add

+ $stdin_child

after

$stderr_child + $stdout_child

I have not tried anything else.

Edited by blckpythn
Link to post
Share on other sites

To keep PowerShell hidden maybe the >COM interface helps.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

Little update: Even though it doesn't show the prompt when using $STDIN_CHILD, I can successfully use the StdinWrite() command.

However, StdoutRead still isn't getting any data or exiting its loop.

Edited by blckpythn
Link to post
Share on other sites

I have a working example I will post on Monday.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

That's the way I grab the PS output:

$sCMD = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command . " & _
            "'D:\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; Enable-Mailbox -Identity " & _
            $Kurzzeichen & " -Alias " & $Kurzzeichen & " -Database " & $sEXDatabase & $sSMTPAddress
    $pid = Run($sCMD, @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
    StdinWrite($pid, @CRLF)
    StdinWrite($pid)
    ; Ausgabe von STDOUT
    $sSTDOUT = ""
    While 1
        $sOutput = StdoutRead($pid)
        If @error Then ExitLoop
        If $sOutput <> "" Then $sSTDOUT = $sSTDOUT & @CRLF & $sOutput
    WEnd
    ; Ausgabe von STDERR
    $sSTDERR = ""
    While 1
        $sOutput = StderrRead($pid)
        If @error Then ExitLoop
        If $sOutput <> "" Then $sSTDERR = $sSTDERR & @CRLF & $sOutput
    WEnd

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

What I posted is only one example and it should grab StdOut and StdErr as soon as Run returned. Try this:

$sCMD = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command . " & _
            "'D:\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; Enable-Mailbox -Identity " & _
            $Kurzzeichen & " -Alias " & $Kurzzeichen & " -Database " & $sEXDatabase & $sSMTPAddress
    $pid = Run($sCMD, @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)
    StdinWrite($pid, @CRLF)
    StdinWrite($pid)
    ; Ausgabe von STDOUT
    $sSTDOUT = ""
    While 1
        $sOutput = StdoutRead($pid)
        If @error Then ExitLoop
        If $sOutput <> "" Then 
          $sSTDOUT = $sSTDOUT & @CRLF & $sOutput
          ConsoleWrite($sOutput & @CRLF)
        EndIf
    WEnd
    ; Ausgabe von STDERR
    $sSTDERR = ""
    While 1
        $sOutput = StderrRead($pid)
        If @error Then ExitLoop
        If $sOutput <> "" Then 
            $sSTDERR = $sSTDERR & @CRLF & $sOutput
            ConsoleWrite($sOutput & @CRLF)
        EndIf
    WEnd

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

 

What I posted is only one example and it should grab StdOut and StdErr as soon as Run returned. Try this:...

The thing is, I'm running powershell with -NoExit because I'm having to authenticate with O365 and that involves running a few commands sequentially.

Then I have to leave that session open to let the user pass commands to. So the proccess doesn't send an @error to StderrRead. Therefor, it doesn't return anything until after the session is ended.

This doesn't help me because I need the errors DURING the session.

I have to run

$LiveCred = Get-Credential <--they need to provide their credentials or I will have them input it earlier and automate it.

Then $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic –AllowRedirection

Then Import-PSSession $Session

Then Connect-MsolService <--again, credentials needed.

After all that, they can start resetting passwords and whatnot, but I want to monitor for errors WHILE powershell is still open.

 

Am I not making sense or doing it stupidly?

Link to post
Share on other sites

Makes sense.

In this case I would have a look at the PS COM interface as I have posted before. Seems to allow to send command by command and return the result in a buffer.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

Makes sense.

In this case I would have a look at the PS COM interface as I have posted before. Seems to allow to send command by command and return the result in a buffer.

I followed the link in that post but cannot find the ActiveXPoSH download.

Link to post
Share on other sites

Did you register an account as described >here?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

Then I suggest to PM ptrex because he is the author of the OP.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

Don't think it counts as recro-posting. It is just helpful for others :)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites
  • Solution

Got it!

Using ActiveXPosh, the example of:

Func ExecuteCMD($sPSCmd)
 Dim $outtext
 ; Set the $OUTPUT mode to $BUFFER
 $ActiveXPosh.OutputMode = $OUTPUT_BUFFER
 $ActiveXPosh.Execute($sPSCmd)

 ; Get the $OUTPUT line by line and add it to a variable
 For $str In $ActiveXPosh.OUTPUT()
   $outtext =  $outtext & $str
  $outtext =  $outtext & @CRLF
 Next

 ; Alternatively you can get the $OUTPUT as a single String
; $outtext = $ActiveXPosh.OutputString
 ConsoleWrite ($outtext & @CR)

 $ActiveXPosh.ClearOutput() ; Empty the $OUTPUT $BUFFER
EndFunc

Works perfectly for getting the return of individual commands without "exiting" the session.

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By noellarkin
      This is the AutoIt script I'm using:
       
      #include <AutoItConstants.au3> Local $Python = "C:\Program Files\Python38" Local $Script = "levenstein.py" Local $String1Path = @ScriptDir & "\string1.txt" Local $String2Path = @ScriptDir & "\string2.txt" Local $Arguments = '"' & $String1Path & '" "' & $String2Path & '"' Local $Concat = $Script & " " & $Arguments ConsoleWrite(@CRLF & $Concat) Local $RunIt = Run(@ComSpec & " /c " & $Concat, @ScriptDir, @SW_HIDE, $STDERR_MERGED) $Output = StdOutRead($RunIt) ConsoleWrite(@CRLF & "Output:" & $Output) It calls the following Python script (levenstein.py):
       
      import re import sys import editdistance def main(): # Check if there are 2 command line arguments if len(sys.argv) != 3: print("Error: Two file paths must be provided") return # Read the contents of the files filepath1 = sys.argv[1] filepath2 = sys.argv[2] string1 = read_file_contents(filepath1) string2 = read_file_contents(filepath2) # Calculate and print the similarity between the two strings similarity = calculate_similarity(string1, string2) print(similarity) def read_file_contents(filepath): # Read the contents of a file into a string with open(filepath, 'r') as f: return f.read() def calculate_similarity(string1, string2): # Calculate the similarity between two strings return 100 - (100 * editdistance.eval(string1, string2) / max(len(string1), len(string2))) # Run the main function if __name__ == '__main__': main() It's working when I run it from cmd, but not when I use AutoIt.

      My AutoIt console looks like this:
       
      levenstein.py "C:\test\Autoit Python\string1.txt" "C:\test\Autoit Python\string2.txt" Output: Whereas when I run the exact same command in cmd levenstein.py "C:\test\Autoit Python\string1.txt" "C:\test\Autoit Python\string2.txt" I get an output that's more like 77.08934 which is what I would expect from the .py script.
      I believe I must be making a mistake in the way I'm using the Run command.
       
      Note: I'm using Python for Edit Distance because the files I'm comparing are rather large, and I'm not sure if the code snippets I found in the Autoit forum would be effective.
    • By DannyJ
      $sCommands1 = 'powershell.exe Get-ChildItem' $iPid = run($sCommands1   , @WorkingDir , @SW_SHOW , 0x2) $sOutput = ""  While 1     $sOutput &= StdoutRead($iPID)         If @error Then             ExitLoop         EndIf  WEnd ;~ msgbox(0, '' , $sOutput) ConsoleWrite("$sOutput") ConsoleWrite($sOutput) ConsoleWrite(@CRLF) $aOutput = stringsplit($sOutput ,@LF , 2) For $i=0 To  UBound($aOutput) - 1 Step 1     ConsoleWrite($aOutput[$i]) Next The script above reads the whole directory into a one dimensional array, but I need to work with the array, so I need to split the array into multiple dimensions.
      I have already read some forum answers here, and I have already tried these commands:
       
      Are there any way to use the $aOutput variable like in PowerShell:
      PowerShell:
      $a = Get-ChildItem $a.Mode I imagine this in AutoIt  $aOutput
      ConsoleWrite($aOutput[i].Mode) Or if I split this command into 2 dimension like:
      For $i To UBound($aOutput)-1 Step 1 ConsoleWrite($aOutput[$i][1]) ConsoleWrite($aOutput[$i][2]) Next  
    • By DannyJ
      If I try to run this script with   Get-ChildItem which means dir this script works perfectly, but If I try to run this command Get-RDUserSession, my script has the following error message:
      This command runs perfectly in PowerShell admin and I get back the values
      Get-RDUserSession -ConnectionBroker  broker.local | sort Username Or you can try this command as well
      Get-Command Get-RDUserSession If I run the above mentioned command this runs perfectly in PowerShell but not with AutoIt.
      Here is my script you can test the commands:
      #include<array.au3> $iPid = run('powershell Get-Command Get-RDUserSession'  , @WindowsDir , @SW_HIDE , 0x2) ;; This command not works in AutoIT you can test it in PowerShell but it won't work in Autoit ;$iPid = run('powershell Get-RDUserSession -ConnectionBroker  broker.local | sort Username'  , @WindowsDir , @SW_MAXIMIZE , 0x2) ; This command not works in AutoIT ;$iPid = run('powershell Get-ChildItem | sort Name'  , @WindowsDir , @SW_HIDE , 0x2) ; This runs perfectly $sOutput = ""  While 1     $sOutput &= StdoutRead($iPID)         If @error Then             ExitLoop         EndIf  WEnd ;~ msgbox(0, '' , $sOutput) $aOutput = stringsplit($sOutput , @LF , 2) _ArrayDisplay($aOutput)  
      That could be the solution of the problem if I could run, directly this PowerShell command window and Write to it and save it's values.
    • By DrLarch
      I'm trying to run this powershell command from Autoit and can't figure out how to pull it off:
      Get-ProvisionedAppxPackage -Online | Where-Object { $_.PackageName -match "xbox" } | ForEach-Object { Remove-ProvisionedAppxPackage -Online -AllUsers -PackageName $_.PackageName } I've been trying to run it many different ways including:
      $sCMD = 'Get-ProvisionedAppxPackage -Online | Where-Object { $_.PackageName -match "xbox" } | ForEach-Object { Remove-ProvisionedAppxPackage -Online -AllUsers -PackageName $_.PackageName }' RunWait(@comspec & ' /c powershell.exe -nologo -executionpolicy bypass -noprofile -Command "&' & $sCMD & '"') The problem is that it seems I'm missing something in how to escape or double the quotes. I've tried doubling the quotes in many different ways, but the end result always produces a syntax error in powershell. I could just run powershell first, then paste and run the command, then close the powershell window, but that's clunky. I'm trying to do it either via parameter (as above) or in one line like this:
      RunWait(@comspec & ' /c powershell.exe -nologo -executionpolicy bypass -noprofile -Command "&Get-ProvisionedAppxPackage -Online | Where-Object { $_.PackageName -match "xbox" } | ForEach-Object { Remove-ProvisionedAppxPackage -Online -AllUsers -PackageName $_.PackageName }"')  
    • By antonioj84
      any assistance how to incorporate this powershell command within autoit
       
      powershell.exe -nologo -executionpolicy bypass -WindowStyle hidden -noprofile -command "&Set-WinUserLanguageList -LanguageList fr-CA, en-CA -Force"
×
×
  • Create New...