david1337

Run powershell script with AutoIt

26 posts in this topic

#1 ·  Posted (edited)

Hi guys,

I need a little help here :)

I have this simple Powershell script, that is able to set "sig.htm" as signature in OWA for the mail account specified.
First part of the script just loads the Exchange snapin, since this is needed for the Get-Mailbox command.

#Add Exchange 2010/2013 snapin if not already loaded in the PowerShell session
if (!(Get-PSSnapin | where {$_.Name -eq "Microsoft.Exchange.Management.PowerShell.E2010"}))
{
	try
	{
		Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP
	}
	catch
	{
		#Snapin was not loaded
		Write-Warning $_.Exception.Message
		EXIT
	}
	. $env:ExchangeInstallPath\bin\RemoteExchange.ps1
	Connect-ExchangeServer -auto -AllowClobber
}



$mailboxes = Get-Mailbox -Identity user@domain.com
$mailboxes| foreach {$file= "sig.htm"; Set-MailboxMessageConfiguration -identity $_.alias -SignatureHtml "$(Get-Content -Path $file -ReadCount 0)"}

What I want is for AutoIt to use Powershell.exe to run the script somehow. This way I would be able to use AutoIt variables and arrays together with the PS script.

 I guess the solution would be to run Powershell.exe with command line arguments?

If that is not possible, maybe have the script stored as a "ps1" file, and interact with it that way? (not preferred)

Edited by david1337

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Try: 

or
 

Powershell.exe -File C:\my_path\run_import_script.ps1

powershell -executionpolicy bypass -File C:\my_path\run_import_script.ps1

powershell.exe -noexit "& 'C:\my_path\run_import_script.ps1'"

 

Edited by You

Regards,
 

Share this post


Link to post
Share on other sites

#3 ·  Posted

Hi You,

Thank you for your answer! :)

Your suggestion is fine to just start the ps1 script from AutoIt, but I want to use it with AutoIt variables.
-> For instance: When the PS script uses "user@domain.com", it should use the $email variable from AutoIt instead.
Or run the PS script for each email address found in my Autoit Array.

 

Share this post


Link to post
Share on other sites

#4 ·  Posted

Try:

Global Const $iPSfile=@TempDir&"\exc.ps1"
Global Const $iHTMLfile="sig.htm"
Global Const $iDefaultEmail="user@domain.com"
Global Const $exPSscript="#Add Exchange 2010/2013 snapin if not already loaded in the PowerShell session"&@CRLF
$exPSscript&='if (!(Get-PSSnapin | where {$_.Name -eq "'&'Microsoft.Exchange.Management.PowerShell.E2010"}))'&@CRLF
$exPSscript&="{"&@CRLF
$exPSscript&="  try"&@CRLF
$exPSscript&="  {"&@CRLF
$exPSscript&="      Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP"&@CRLF
$exPSscript&="  }"&@CRLF
$exPSscript&="  catch"&@CRLF
$exPSscript&="  {"&@CRLF
$exPSscript&="      #Snapin was not loaded"&@CRLF
$exPSscript&="      Write-Warning $_.Exception.Message"&@CRLF
$exPSscript&="      EXIT"&@CRLF
$exPSscript&="  }"&@CRLF
$exPSscript&="  . $env:ExchangeInstallPath\bin\RemoteExchange.ps1"&@CRLF
$exPSscript&="  Connect-ExchangeServer -auto -AllowClobber"&@CRLF
$exPSscript&="}"&@CRLF
$exPSscript&=""&@CRLF
$exPSscript&="$mailboxes = Get-Mailbox -Identity "&$iDefaultEmail&@CRLF
$exPSscript&='$mailboxes| foreach {$file= "'&$iHTMLfile&'"; Set-MailboxMessageConfiguration -identity $_.alias -SignatureHtml '&'"$(Get-Content -Path $file -ReadCount 0)'&'"}'&@CRLF

Global $PSscript, $ListEmail=StringSplit("my@gmail.com|ceo@viper.com|xxx@xxx.com","|")

For $i=1 to $ListEmail[0]-1
    $PSscript=StringReplace($exPSscript,$iDefaultEmail,$ListEmail[$i])
    _SaveExecute($PSscript)
    $PSscript=""
Next

Func _SaveExecute($PSscript)
    Local $hFile=FileOpen($iPSfile,2+8)
    FileWrite($hFile,$PSscript)
    FileClose($hFile)
;~  _ExecutePSfile($iPSfile)
;~ Do more somethink
EndFunc

 


Regards,
 

Share this post


Link to post
Share on other sites

#5 ·  Posted

You should be able to add the following to your PowerShell Script to accept parameters:

Example: PScript.ps1 -Email mail@gmail.com, -File @ScriptDir\Sig.htm

param (
    [Parameter(Mandatory=$true)][string]$Email,
    [string]$File)
 )

 

Share this post


Link to post
Share on other sites

#6 ·  Posted

Hi again You,

Wow this looks very interesting! :)

I get Error: Line 5 - Cannot assign values to constants

Share this post


Link to post
Share on other sites

#7 ·  Posted

Hi Subz,

Thanks for your answer!

Okay so I add this to my ps1 file:

param (
    [Parameter(Mandatory=$true)][string]$Email,
    [string]$File)
 )

 

and how would I call the file correctly from AutoIt?

Share this post


Link to post
Share on other sites

#8 ·  Posted

5 hours ago, You said:

Try: 

or
 

Powershell.exe -File C:\my_path\run_import_script.ps1

powershell -executionpolicy bypass -File C:\my_path\run_import_script.ps1

powershell.exe -noexit "& 'C:\my_path\run_import_script.ps1'"

 

FYI, You, I have actually looked into the first suggestion you made concerning the Powershell Com object, but if you dig into the issue a little more, you will find that that method is only useful up to powershell version 3.  If you have any version greater than that, it is useless.

Share this post


Link to post
Share on other sites

#9 ·  Posted

Here is a really basic example:

Example.ps1

param (
    [Parameter(Mandatory=$true)][string]$Email,
    [string]$File)

write-output $Email
write-output $File

Example.au3

Global $aUserInfo[2][2]
    $aUserInfo[0][0] = 'First.User@google.com'
    $aUserInfo[0][1] = @TempDir & '\First.User-Sig'
    $aUserInfo[1][0] = 'Second.User@google.com'
    $aUserInfo[1][1] = @TempDir & '\Second.User-Sig.htm'

For $i = 0 To UBound($aUserInfo) - 1
    RunWait(@ComSpec & ' /k PowerShell.exe -ExecutionPolicy Bypass -File "' & @ScriptDir & '\Example.ps1" -Email ' & $aUserInfo[$i][0] & '-File "' & $aUserInfo[$i][1] & '"')
Next

 

Share this post


Link to post
Share on other sites

#10 ·  Posted

Here is another options similar to @You suggestion although haven't tested this, you will need to uncomment the RunWait to test.

Global $sPSScript = @TempDir & "\PSScript.ps1"
Global $aUserInfo[2][2]
    $aUserInfo[0][0] = 'First.User@google.com'
    $aUserInfo[0][1] = @TempDir & '\First.User-Sig'
    $aUserInfo[1][0] = 'Second.User@google.com'
    $aUserInfo[1][1] = @TempDir & '\Second.User-Sig.htm'

    For $i = 0 To UBound($aUserInfo) - 1
        _PSScript($aUserInfo[$i][0], $aUserInfo[$i][1])
    Next

Func _PSscript($sEmail, $sFile)
    Local $hPSScript, $sPSWrite = ""
        $sPSWrite &= "#Add Exchange 2010/2013 snapin if not already loaded in the PowerShell session" & @CRLF
        $sPSWrite &= 'if (!(Get-PSSnapin | where {$_.Name -eq "'&'Microsoft.Exchange.Management.PowerShell.E2010"}))' & @CRLF
        $sPSWrite &= "{" & @CRLF
        $sPSWrite &= "  try" & @CRLF
        $sPSWrite &= "  {" & @CRLF
        $sPSWrite &= "      Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP" & @CRLF
        $sPSWrite &= "  }" & @CRLF
        $sPSWrite &= "  catch" & @CRLF
        $sPSWrite &= "  {" & @CRLF
        $sPSWrite &= "      #Snapin was not loaded" & @CRLF
        $sPSWrite &= "      Write-Warning $_.Exception.Message" & @CRLF
        $sPSWrite &= "      EXIT" & @CRLF
        $sPSWrite &= "  }" & @CRLF
        $sPSWrite &= "  . $env:ExchangeInstallPath\bin\RemoteExchange.ps1" & @CRLF
        $sPSWrite &= "  Connect-ExchangeServer -auto -AllowClobber" & @CRLF
        $sPSWrite &= "}" & @CRLF
        $sPSWrite &= "" & @CRLF
        $sPSWrite &= "$mailboxes = Get-Mailbox -Identity " & $sEmail & @CRLF
        $sPSWrite &= '$mailboxes| foreach {$file= "' & $sFile & '"; Set-MailboxMessageConfiguration -identity $_.alias -SignatureHtml ' & '"$(Get-Content -Path $file -ReadCount 0)' & '"}' & @CRLF
        $hPSScript = FileOpen($sPSScript, 10)
            If @error Then Return
        FileWrite($sPSScript, $sPSWrite)
        FileClose($hPSScript)
;~  RunWait(@ComSpec & ' /k PowerShell.exe -ExecutionPolicy Bypass -File "' & $sPSScript & '"')
EndFunc

 

1 person likes this

Share this post


Link to post
Share on other sites

#11 ·  Posted

53 minutes ago, Subz said:

Here is another options similar to @You suggestion although haven't tested this, you will need to uncomment the RunWait to test.

Global $sPSScript = @TempDir & "\PSScript.ps1"
Global $aUserInfo[2][2]
    $aUserInfo[0][0] = 'First.User@google.com'
    $aUserInfo[0][1] = @TempDir & '\First.User-Sig'
    $aUserInfo[1][0] = 'Second.User@google.com'
    $aUserInfo[1][1] = @TempDir & '\Second.User-Sig.htm'

    For $i = 0 To UBound($aUserInfo) - 1
        _PSScript($aUserInfo[$i][0], $aUserInfo[$i][1])
    Next

Func _PSscript($sEmail, $sFile)
    Local $hPSScript, $sPSWrite = ""
        $sPSWrite &= "#Add Exchange 2010/2013 snapin if not already loaded in the PowerShell session" & @CRLF
        $sPSWrite &= 'if (!(Get-PSSnapin | where {$_.Name -eq "'&'Microsoft.Exchange.Management.PowerShell.E2010"}))' & @CRLF
        $sPSWrite &= "{" & @CRLF
        $sPSWrite &= "  try" & @CRLF
        $sPSWrite &= "  {" & @CRLF
        $sPSWrite &= "      Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP" & @CRLF
        $sPSWrite &= "  }" & @CRLF
        $sPSWrite &= "  catch" & @CRLF
        $sPSWrite &= "  {" & @CRLF
        $sPSWrite &= "      #Snapin was not loaded" & @CRLF
        $sPSWrite &= "      Write-Warning $_.Exception.Message" & @CRLF
        $sPSWrite &= "      EXIT" & @CRLF
        $sPSWrite &= "  }" & @CRLF
        $sPSWrite &= "  . $env:ExchangeInstallPath\bin\RemoteExchange.ps1" & @CRLF
        $sPSWrite &= "  Connect-ExchangeServer -auto -AllowClobber" & @CRLF
        $sPSWrite &= "}" & @CRLF
        $sPSWrite &= "" & @CRLF
        $sPSWrite &= "$mailboxes = Get-Mailbox -Identity " & $sEmail & @CRLF
        $sPSWrite &= '$mailboxes| foreach {$file= "' & $sFile & '"; Set-MailboxMessageConfiguration -identity $_.alias -SignatureHtml ' & '"$(Get-Content -Path $file -ReadCount 0)' & '"}' & @CRLF
        $hPSScript = FileOpen($sPSScript, 10)
            If @error Then Return
        FileWrite($sPSScript, $sPSWrite)
        FileClose($hPSScript)
;~  RunWait(@ComSpec & ' /k PowerShell.exe -ExecutionPolicy Bypass -File "' & $sPSScript & '"')
EndFunc

 

 

Wow, I think that we are very close now.
But there seems to be a problem with running a ps1 script that includes the Exchange snapin.
I get the below error in the cmd window:

WARNING: The Windows PowerShell snap-in
'Microsoft.Exchange.Management.PowerShell.E2010' is not installed on this
machine.

 

I tried to run another ps1 script that didn't contain the exchange snapin, and that worked fine using the Run command from AutoIt.

What could be the problem?

Share this post


Link to post
Share on other sites

#12 ·  Posted

The creation of the ps1 scripts works perfectly though.

I tried (Run with Powershell) on the ps1 script that was created in the temp folder by AutoIt, and it worked just as expected!

So the only problem is to execute the ps1 script directly from AutoSig :)

Share this post


Link to post
Share on other sites

#13 ·  Posted

You could try adding #RequireAdmin to the top of you Au3 Script if that doesn't work you can try using the line below which will Start PowerShell in Admin mode

RunWait(@ComSpec & ' /k PowerShell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList ' & "'-ExecutionPolicy Bypass -File " & '""' & $sPSScript & '"' & "' -Verb RunAs}")

 

Share this post


Link to post
Share on other sites

#14 ·  Posted

Its 4am in the morning here and got work in 4 hours so going to go now to get some zzz, I'm fairly sure that the issue is running PowerShell in Admin mode so hopefully either of the commands above will work for you.

Share this post


Link to post
Share on other sites

#15 ·  Posted

Wow okay you must be pretty tired atm then. have a good nights sleep!

I tried both RequireAdmin and starting PS in Admin mode, but both gave the result to just leave an empty cmd window open, and no signature was set. (No errors this time though)

You got me very close to the finish line, and I will just have to figure out why the script won't run from AutoIT!

Thank you very much for the help!

 

Share this post


Link to post
Share on other sites

#16 ·  Posted

After 

FileClose($hPSScript)

Can you try using:

ShellExecute($sPSScript)

Share this post


Link to post
Share on other sites

#17 ·  Posted

ShellExecute will open the file with Windows' default behavior. In this case it will just open the ps1 file in edit mode.

 

But I found out that if I start the script with a batch file like this, it works:
 

Powershell.exe -executionpolicy Bypass -File  "TempFolder...\PSScript.ps1"

So I'm sure that I can get it to work from AutoIt somehow also! :)

Share this post


Link to post
Share on other sites

#18 ·  Posted

Can you try:

ShellExecute('PowerShell.exe', '-executionpolicy Bypass -File "' & $sPSScript & '"')

 

Share this post


Link to post
Share on other sites

#19 ·  Posted

Same result:
'Microsoft.Exchange.Management.PowerShell.E2010' is not installed on this
machine.


Weird !

Share this post


Link to post
Share on other sites

#20 ·  Posted

Do you run CMD in Administrative mode?  When running PowerShell?  Can you manually try using the same command line and see what the result is?

Share this post


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

  • Similar Content

    • tcox8
      By tcox8
      Hello,
      Currently I am running a script that calls a powershell script. To read the results of that I am reading StdOut. I am parsing things accordingly but unfortunately it doesn't parse correctly all the time and I end up missing parts of the string or other problems. My question then is, what is the best results for reading what is returned when running a powershell script or something similar?
    • WoodGrain
      By WoodGrain
      Hi guys,
      This is probably an obvious one, but I really don't use this command at all so am hoping you can spot my mistake.
      I'm running a powershell script on a schedule with the following script in a function, the function is being called in a loop, but the console process is not closing in the background and I end up with a bunch of console windows running in the background:
      Run(@comspec & ' /k PowerShell.exe -STA -NonInteractive -ExecutionPolicy ByPass -Command "& ''Z:\Powershell\365\GetNextDetails.ps1'' "', "", @SW_HIDE) Thanks!
    • caramen
      By caramen
      !Arf it i used [Start new topic] when i was in GUI section and the post was moved without i even noticed it. Can an admin move that to general (SORRY)!
       
      Hello guys ME again and my ugly english xD.
       
      This is the only one powershell command i am not able to use becose i dont found a way to insert the USERNAME $Variable at the first line. i am not able to find a third way to QUOTE a variable when i use "*" for the AutoIt command and the '*' for the PS command but i need to QUOTE inside the '*'PS command my $Variable
       
      $iPid = run("powershell get-aduser -Filter {sn -eq 'USERNAME'} -Properties sAMAccountName,Title" , @WindowsDir , @SW_HIDE , 0x2) $AllInfo = "" While 1 $AllInfo &= StdoutRead($iPID) If @error Then ExitLoop EndIf WEnd $AllInfo = stringsplit($AllInfo , @LF , 2) ;split result in all @LF but don't use the splitted result for anything _ArrayDisplay($AllInfo) This gonna be my last question becose i can do all the rest (i guess & wish ) alone
       
    • caramen
      By caramen
      Hello.
      I improved my powershell skill like F**** !! I am so happy Level skill under beginner HAHA well i am just getting what i want but now i got a question about autoit + powershell
      When i run that Shellcommand 
      $iPid = run("Powershell Get-ADUser USER -Properties * | select -Expand Title"  , @WindowsDir , @SW_HIDE , 0x2)
       
      The return valu is :
      Micro r,seau (this is normal in PowerShell)
      Can i transform the value
      Micro réseau with autoit 
    • profyt7
      By profyt7
      Hey Guys,
      I am almost there but feel I am missing something that is right in front of me and need another set of eyes.
       
      I am trying to run the following powershell file with the following parameters. This works in powershell just fine.
      Reset-LocalAdminPassword.ps1 -Password $secureString
       
      I created an autoit script to do a few other things but from venturing in the forums I found some code and did the following:
      ;THIS COMMAND WILL RUN THE powershell script
      $iDir = "C:\test\script\Reset-LocalAdminPassword.ps1"
      Run('cmd /k C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File ' & '"' & $iDir & '-Password $secureString')
      Sleep(15000)
       
      The problem is that when it runs it gives me a message that C:\test\script\Reset-LocalAdminPassword.ps1-Password $secureString' is not a valid ps1 file.
      I cannot seem to get it to run the ps1 file with the -Password $secureString' parameter. It keeps cobining the ps1 path and the parameters all as one.
      I am sure this is something I am overlooking but I have been battling with this for a few hours now and just don't know what I am missing.