http://www.perlmonks.org?node_id=1025977


in reply to How to handle a browser window that opens up during the execution of some external program commands

Post the Powershell code that launches and manipulates IE, and I'll tell you how to handle the trivial part of filling in fields. The PS code is already using something to automate IE, and... oh wait, this is a Perl forum, not a Powershell forum.

If you must take control of a window using Perl, on Windows, that was launched by another process (Powershell in this case), then Win32-GuiTest is probably your best bet...

  • Comment on Re: How to handle a browser window that opens up during the execution of some external program commands

Replies are listed 'Best First'.
Re^2: How to handle a browser window that opens up during the execution of some external program commands
by sundialsvc4 (Abbot) on Mar 28, 2013 at 15:31 UTC

    Nevermind what forum this is ... we all encounter issues like this every day.   Bring the topic to closure here (too...), please.   PowerShell scripts will be understood by all comers.

      I asked the OP to post the powershell code, and offered to help with it

        Hi guys, sorry for delay, please see below powershell code-

        # requires -version 2.0 [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windo +ws.Forms") # Directory where this script is located $CommonDir = Split-Path $MyInvocation.MyCommand.Path # Dot-Source includes from our common library . $CommonDir\ConvertFrom-JSON.ps1 # Where to cache the access token $script:SepmDefaultConnectionFile = "$env:LOCALAPPDATA\SepmRmmWS_Cache +dToken.txt" Set-StrictMode -Version 2.0 trap { "Error in Get-SepmRmmWsAccessToken: $_"; break } if ($host.Runspace.ApartmentState -ne 'STA') { $msg = "Get-SepmRmmWsAccessToken may only be run in Single Threade +d Appartment (STA) mode. For example, PowerShell ISE, or PowerShell.e +xe -STA." Write-Verbose $msg throw $msg } function ConvertFrom-Xml($XML) { foreach ($Object in @($XML.Objects.Object)) { $PSObject = New-Object PSObject foreach ($Property in @($Object.Property)) { $PSObject | Add-Member NoteProperty $Property.Name $Proper +ty.InnerText } $PSObject } } <# .Synopsis Read an access token from the cache file and decrypt it. .Description Read an access token from the cache file and decrypt it. The file is encrypted to limit access to the current user via Conver +tFrom-SecureString. .Parameter FileName Path to file where the connection data should be saved, default is $SepmDefaultConnectionFile. .Example # Write default connection data to default location $AccessTokenPSObject = Get-SepmWsConnectionFromCache #> function Get-SepmWsConnectionFromCache { [CmdletBinding()] Param( [string][ValidateNotNullOrEmpty()]$FileName = $SepmDefaultConn +ectionFile ) Write-Verbose "Read access token from file $FileName" Set-StrictMode -Version 2.0 trap { "Error in Get-SepmWsConnectionFromCache: $_"; break } $encryptedString = Get-Content $FileName $secureString = ConvertTo-SecureString -String $encryptedString [String]$xmlString = [Runtime.InteropServices.Marshal]::PtrToStrin +gAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureSt +ring)); $xml = New-Object XML $xml.LoadXml($xmlString) return ConvertFrom-Xml($xml) } <# .Synopsis Save an access token in encrypted format to a cache file. .Description Save an access token in encrypted format to a cache file. The file is encrypted to limit access to the current user via Conver +tFrom-SecureString. .Parameter AccessToken Access token string. .Parameter FileName Path to file where the connection data should be saved, default is $SepmDefaultConnectionFile. .Example # Write default connection data to default location Get-SepmRmmWsAccessToken.access_token | Write-SepmWsConnectionToCac +he #> function Write-SepmWsConnectionToCache { Param( [parameter(Mandatory=$true)]$AccessTokenPSObject, [string][ValidateNotNullOrEmpty()]$FileName = $SepmDefaultConn +ectionFile ) Write-Verbose "Caching access token $($AccessTokenPSObject.access_ +token) as encrypted data to file $FileName" $xml = ConvertTo-Xml $AccessTokenPSObject $xmlString = $xml.OuterXml ConvertTo-SecureString -String $xmlString -AsPlainText -Force | Co +nvertFrom-SecureString | Set-Content $FileName } <# .Synopsis Add the access token to the webservice proxy objects URL property. Th +is will ensure that all reqeusts using the webservice proxy have the access token attached. .Description We alter the webservice proxy URL to append the access token for SOAP + authentication. However, this URL change perisists the next time you try to obtain th +e web service - even if you dispose of the web service. It will persist until you quit the process that created the webservic +e (e.g. PowerGUI Script Editor). This method insures that any old bearer_token parameters are removed +before adding the new bearer_token. #> function Set-AccessToken { Param([parameter(Mandatory=$true)] $Webservice, [string][parameter(Mandatory=$true)] $AccessToken) $accessTokenName = "access_token" $url = $Webservice.get_Url() $index = $url.IndexOf($accessTokenName) # If a previous access token is present remove it if ($index -gt 0) { # Strip bearer_token plus the ? that precedes it. $url = $url.SubString(0, $index - 1) } # Add the access token to the url $Webservice.set_Url($url + "?$accessTokenName=$AccessToken") return $Webservice } <# .Synopsis Prompt the user for credentials and then retrieve the AccessToken ob +ject. .Description Prompt the user for credentials and then retrieve the AccessToken ob +ject. This method will report an error if it is not run in STA mode, which means either PowerShell ISE or PowerShell.exe -STA. .Parameter HostName The hostname or IP of the SEPM server computer. .Parameter Port The port number of the SEPM tomcat server. This is not the web servi +ce port. This is the scm.server.port value found in the config.properties fil +e. .Parameter ClientId Normally an administrator will register a new client ID, store it in + HostParameters.ps1 and this value will be read from that file. .Example # Get the access token object after the user provides authenticatio +n credentials. $AccessTokenPSObject = Get-SepmRmmWsAccessToken # Get the access token object after the user provides authenticatio +n credentials with verbose logging. $AccessTokenPSObject = Get-SepmRmmWsAccessToken -Verbose #> function Get-SepmRmmWsAccessToken { [CmdletBinding()] Param( [ValidateNotNullOrEmpty()]$configFile = "$($CommonDir)\..\Conf +ig.xml", [string]$HostName, [string]$Port, [string]$ClientId, [string]$ClientSecret ) # Read our config file [xml]$config = Get-Content $configFile # Validate our params if($HostName.trim() -eq "") {$HostName = $config.SepmWS.Hos +tName} if($Port.trim() -eq "") {$Port = $config.SepmWS.PortNo} if($ClientId.trim() -eq "") {$ClientId = $config.SepmWS.Cli +entId} if($ClientSecret.trim() -eq "") {$ClientSecret = $config.SepmWS +.ClientSecret} Write-Verbose "Get-SepmRmmWsAccessToken -HostName $HostName -Port +$Port -ClientId $ClientId -ClientSecret $ClientSecret" $window = New-Object System.Windows.Forms.Form $window.AutoSize = $true $browser = New-Object System.Windows.Forms.WebBrowser $browser.Width = "800" $browser.Height = "600" $window.Controls.Add($browser) $base="https://$($HostName):$($Port)" $responseType = "response_type=code" $ClientId = "&client_id=$($ClientId)" # redirect URI would normally be the RMM tool web app; # we just need to specify a page that doesn't require authenticati +on - our login page. $redirectUri = "&redirect_uri=https://$($HostName):$($Port)/sepm" $loginUri = $base + "/sepm/oauth/authorize?" + $responseType + $Cl +ientId + $redirectUri write-verbose "$loginUri" # PS one-liner that ignores certificate errors such as self-signed + certificates [System.Net.ServicePointManager]::ServerCertificateValidationCallb +ack ={$true} $browser.Navigate($loginUri) $browser.add_Navigated({ $auth_token_key = "code" Write-Verbose "Get-SepmRmmWsAccessToken: Navigate event: Uri $ +($_.Url)" $oauthResult = $_.Url.Query $oauthResult = $oauthResult.TrimStart("?") $oauthResult = $oauthResult.Replace("&", "`n") $queryHashTable = ConvertFrom-StringData -StringData $oauthRes +ult if ($queryHashTable.ContainsKey($auth_token_key)) { $authToken = $queryHashTable[$auth_token_key]; Write-Verbose "Get-SepmRmmWsAccessToken: Obtained $auth_to +ken_key which is used to get the OAuth access token" $window.Close() } else { Write-Verbose "Get-SepmRmmWsAccessToken: Navigate event: c +ould not interpret Uri $($_.Url)" # error handling TBD } }) Write-Verbose "Get-SepmRmmWsAccessToken: Displaying GUI to enter u +ser credentials and/or confirm access" [System.Windows.Forms.Application]::Run($window) $clientSecretParam = "&client_secret="+$ClientSecret $authKey= "&"+$auth_token_key+"="+$authToken $access_url = $base + "/sepm/oauth/token?grant_type=authorization_ +code" + $ClientId + $clientSecretParam + $redirectUri + $authKey Write-Verbose "Get-SepmRmmWsAccessToken: Use auth token key to +download access token @ $access_url" $wc = new-object net.WebClient $jsonData = $wc.downloadString($access_url) $AccessTokenPSObject = ConvertFrom-JSON -json $jsonData if ($AccessTokenPSObject.access_token) { Write-Host "OAuth 2.0 Access Token Information for $HostName" Write-Host "-------------------------------------------------- +-------------------" "token_type: $($AccessTokenPSObject.token_type)" | Write-Ho +st "access_token: $($AccessTokenPSObject.access_token)" | Write- +Host "refresh_token: $($AccessTokenPSObject.refresh_token)" | Write +-Host "expires_in: $($AccessTokenPSObject.expires_in) seconds, wh +ich equals {0:N2} hours" -f ($($AccessTokenPSObject.expires_in)/ (60 +* 60)) | Write-Host Write-Host "-------------------------------------------------- +-------------------" } return $AccessTokenPSObject }

        Check the above code and see how can I avoid this browser window and pass the credentials using command line

Re^2: How to handle a browser window that opens up during the execution of some external program commands
by tarunmudgal4u (Sexton) on Apr 08, 2013 at 07:38 UTC

    Hi, I'm trying to use Win32-GuiTest for this problem. Below is my observation while using this module. please let me know your suggestions on this-

    1. My powershell initiated browser window doesn't has any title. So, I'm using FindWindowLike with class regex. It works somehow okay but in some scenarios, this class regex matches more windows. Is there any way to get only one window handler?

    2. Once I get the window handler, is there any function to select username, password text boxes and send texts into these text boxes.

    below is the sample code i'm using to identify

    use Win32::GuiTest qw( :ALL ); #use strict; my @whnds = FindWindowLike( undef, "^\s*\$" , "Internet Explorer_S +erver" ); if( !@whnds ){ die "Cannot find window with title/caption Symantec Endpoint P +rotection Manager\n"; }else{ print "window handle found: [@whnds]\n"; } $text = "hi"; foreach (@whnds) { set_front_win($_); $result= WMSetText( $_, $text ); SendKeys("{TAB}"); # sleep(1); SendKeys("admin"); # sleep(1); SendKeys("{TAB}"); # sleep(1); SendKeys("crt{@}123"); # sleep(1); SendKeys("{TAB}"); # sleep(1); SendKeys("{TAB}"); # sleep(1); SendKeys("{ENTER}"); sleep(1); #PushChildButton( undef, "Authorize" ); SendKeys("{ENTER}"); }

      To answer both questions see spy.pl from Win32::GuiTest::Examples. Use this tool (or something similar) to determin the window/object ID. See the other examples for using this ID to interact with them.