Jump to content

Run powershell script with AutoIt


Recommended Posts

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
Link to comment
Share on other sites

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,
 

Link to comment
Share on other sites

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.

 

Link to comment
Share on other sites

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,
 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 :)

Link to comment
Share on other sites

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}")

 

Link to comment
Share on other sites

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!

 

Link to comment
Share on other sites

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! :)

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

×
×
  • Create New...