Required examples on Usuageof COM object Members - powershell

I am new to powershell and Windows COM objects.
I am able to get members of a particular COM object for example Internet Explorer as below:
$ie = New-Object -com internetexplorer.application
$ie | get-member
TypeName: System.__ComObject#{d30c1661-cdaf-11d0-8a3e-00c04fc9e26e}
Name MemberType Definition
---- ---------- ----------
ClientToWindow Method void ClientToWindow (int, int)
ExecWB Method void ExecWB (OLECMDID, OLECMDEXECOPT, Variant, Variant)
GetProperty Method Variant GetProperty (string)
GoBack Method void GoBack ()
But anywhere can I get detailed usuage of each member ?
I mean, how a particular member for example GoBack or Busy or anyothermember can be used in powershell scripts(in a detailed way) ?

Short answer: Nope. Using the get-member like that will give you all the information that you are able to get. Unfortunately there is no "Get-Help iexplore" for COM objects because they are "Black Boxes" where you only see the methods and properties that they decide are public.
Sometimes, you can infer, and experiment to get things to work. For ex.
#Create a new Internet explorer object
$ie = New-Object -com internetexplorer.application
#Show the Internet Explorer window
$ie.Visible = $true
#Navigate to Google
$ie.Navigate("http://google.com")
#Navigate to Yahoo
$ie.Navigate("http://yahoo.com")
#Go back to google
$ie.GoBack()
For anything more complex, searching google is usually the first thing I would do. For ex. some links:
The Internet Explorer Object Model
Web UI Automation with Windows PowerShell

Related

creating comobject for AccessObjects

I am trying to create a powershell 'AccessObject' comobject for my MS Access app. Basically, I will trying to create a powershell script that gets queries in a database and the tables and/or queries a particular query depends on. To do that i will need to have an instance of the MS Access 'AccessObject' and 'DependencyInfo' classes in my powershell script. I have attached a snippet of the function i intend to use. This is not the complete function, please note. All i want is to know how to create an instance of the DependencyInfo and AccessObjects in powershell.
function getQueries([string] $database)
{
$dbEng = New-Object -ComObject DAO.DBEngine.120
$AccessApp= New-Object -ComObject Access.Application
$Dependency = $AccessApp.DependencyInfo
$AccessObject=$AccessApp.AccessObjects
...
}
All i want is to know how to create an instance of the DependencyInfo
and AccessObjects in powershell.
The following creates a new Access process, opens a local accdb file, and retrieves the dependencies for a given form:
$db = new-object -ComObject 'Access.Application'
$db.OpenCurrentDatabase('C:\temp\deezNutz.accdb')
$dependency_info = $db.Application.CurrentProject().AllForms('frm_person').GetDependencyInfo()
foreach ($dependency in $dependency_info.Dependencies) { $dependency.FullName }
$db.CloseCurrentDatabase()
$db.Application.DoCmd.Quit()
If you're trying to pro grammatically manipulate the objects in a Microsoft Access database e.g., forms, reports, queries, etc. Your best bet is to search for solutions using VBA then convert those to Powershell. For this example, I first wrote the solution in VBA then converted it to Powershell.
Thanks #Lord Adam. This was really helpful. In my case i had to modify the logic a little bit:
$AccessApp= New-Object -ComObject 'Access.Application'
$AccessApp.OpenCurrentDatabase($database)
$AccessApp.Application.SetOption("Track Name AutoCorrect Info", $true)
$QryDependency = $AccessApp.Application.CurrentData.AllQueries.Item($query.Name).GetDependencyInfo()
ForEach($di in $QryDependency.Dependencies)
{
$QryObjects= $QryObjects + $di.Name +","
}

Running functions with COM objects in parallel

I have four sites which I have to check specific HTML for every so often and I'd like to automate this. I've tried to use Invoke-WebRequest but I couldn't figure out how to step through the pages since a lot of AJAX is being used. This is why I use two IE COM objects. With the COM objects I can easily step through and search for the correct HTML on each page.
The problem is that the checks run sequentially:
#Define functions
site1 { }
site2 { }
etc..
#run functions
$result = site1 #returns bool
$result = site2 #returns bool
etc..
I'd like to have the site checks run at the same time but I have been unable to do so with either Start-Job or a workflow.
I don't think I have figured out the syntax for either option as the Visible property from the IE COM object never triggers:
$url = "somesite.com"
$site = New-Object -COM InternetExplorer.Application
$site.Silent = $true
$site.Navigate($url)
while ($ie.ReadyState -ne 4) {Start-Sleep -m 500}
$site.Visible = $true
What is the proper way to have these site checks run at the same time and also have them be visible?

Can't download files with PowerShell IE COM Object [with login]

I have a script using PowerShells IE COM Object to login to a site and navigate to a page with PDFs (that I wish to download). I am using IE COM object to do all the navigation, and Invoke-WebRequest for the actual download. Issue is when the PDF files download they are size 2kb and can't be opened. I have a strong feeling this is a session issue and IE must be forgetting that I am logged in somehow. Any way to make IE remember I am logged in when so that I can download the files successfully?
Any help appreciated. Thanks.
Edit:
$ie = New-Object -COMObject InternetExplorer.Application
$ie.visible = $true
# Navigate to home page
$ie.navigate($URL)
while ($ie.Busy -eq $true){Start-Sleep -Seconds 3}
$Username = $ie.Document.getElementsByName("userName")
$Username.item(0).value = "username"
$Password = $ie.Document.getElementsByName("password")
$Password.item(0).value = "pass"
$AcceptTerms = $ie.Document.getElementById("useAddtnlField")
$AcceptTerms.checked = $true
$Btn = $ie.Document.getElementsByTagName("span") | ? {$_.title -match 'Login'}
$Btn.click()
while ($ie.Busy -eq $true){Start-Sleep -Seconds 2}
# ---- logged in ----
# -- Opens link in new window (due to JS) --
$ie.Navigate("https://chaseloanmanager.chase.com/Chaselock/ViewOnlineGuide.aspx")
while ($ie.Busy -eq $true){Start-Sleep -Seconds 2}
After that last navigate, I lose the $ie object and can no longer do anything with it. If I create a new $ie2 object, and continue the script using $ie2, the files are unable to be opened when finished. I was also unsuccessful getting access to the window using Shell.Application and Windows() method as to try and reference the original $ie window. Anyways, I think I need to complete the script using the original $ie object so that I am recognized as logged in throughout the process and can have a valid download at the end. Hopefully that makes sense and can help someone help me. Thanks

PowerShell: Using already created objects

$ie = New-Object -com internetexplorer.application
i want to reuse this object when the script runs next time. I don't want to create a new object
You should be able to attach to the process with this, check the result of the Windows() method, locate the IE one and then build the correct where clause:
$ie = (New-Object -ComObject Shell.Application).Windows() | Where-Object {...}

powershell com object windows installer

I would like to leverage the following
$wi=new-object -com WindowsInstaller.Installer
If I do a $wi |gm I do not see the method I want "Products".
I would like to iterate Products and show a list of all items installed on the system.
So I thought... let me do a $wi.gettype().invokemember
Not really sure what to do $wi.gettype().invokemember("Products","InvokeMethod")
or something yields cannot find an overload...
But now I am lost. I have looked elsewhere but I don't want to create a whole XML file. I should be able to access the com objects methods.
If you are trying to get a list of installed programs in Windows, there is a native Powershell way, which is actually using WMI behind the scenes:
Get-WmiObject Win32_Product
Here's a related article from Microsoft Scripting Guys.
It appears that this approach has some issues, so better be avoided.
When you query this class, the way the provider works is that it
actually performs a Windows Installer “reconfiguration” on every MSI
package on the system as its performing the query!
I tried my best to find a solution that involves WindowsInstaller com object, but all of them point to an article that no longer exists. Here is one on stackoverflow.
An alternative solution is to give a try to psmsi on CodePlex.
Here my code-snippet for this:
cls
$msi = New-Object -ComObject WindowsInstaller.Installer
$prodList = foreach ($p in $msi.Products()) {
try {
$name = $msi.ProductInfo($p, 'ProductName')
$ver = $msi.ProductInfo($p, 'VersionString')
$guid = $p
[tuple]::Create($name, $ver, $guid)
} catch {}
}
$prodlist