Powershell com object with parameters - powershell

I want to write a powershell script that will open an Internet Explorer instance as a com object so i can manipulate it. The problem is I need to run it with a parameter to make sure IE is run as a new session.
The parameter I need to pass is -noframemerging I need to pass this so each instance is a new session. Here is the code I've been using to get the instance started.
$ie = new-object -com "InternetExplorer.Application"
If someone could give me a hand figuring out how to be able to create multiple objects as a new session in IE that would be fantastic!

Here is my solution:
$IEProcess = [System.Diagnostics.Process]::Start("iexplore", "-noframemerging")
Sleep -Seconds 1
$ie = $(New-Object -ComObject "Shell.Application").Windows() | ? {$_.HWND -eq $IEProcess.MainWindowHandle}
I launch an instance with the System.Diagnostic.Process library, I was using Start-Process but getting some weird outcomes, this fixed that right up. At this point I have an instance of IE open with the noframemerging switch and a variable pointing the process.
I threw a sleep in there to give the com object a chance to construct before trying to reference it.
Then I grab all the windows com objects and select the one that has a handle (HWND) that is the same as the one from the process I just started and assign it to my $ie variable.
The end result is I have a variable that references a com object of Internet Explorer that is independent of all other sessions. The reason I needed this in particular is I'm opening many instances of IE and logging into a website with different user accounts, if they share a session the login page is skipped and they will already be logged in as the first user that logged in.
Thanks for all the help guys!

Related

Handle a COM event in PowerShell

I am controlling an application via its COM server from PowerShell. This is pretty simple:
# Start the application via COM
$app = New-Object -ComObject CoolApp.Application
# Start a data measurement in the application
$measurement = $app.Measurement
$measurement.Start()
Now comes the hard part: the Measurement object has an event called "OnFinished", that is invoked when the data measurement is done. I would like my powershell script to wait for the occurence of this event.
How can I subscribe to such an COM event PowerShell?
If a Primary Interop Assemblies(PIA) is provided from the developer to the COM object you are using, you can easily register event handlers by using it.
For example, refer to this description.
Registering and Catching Communicator 2007 Automation API Events
Like the above components and Office, PIA is provided for many of Microsoft's products.
Office primary interop assemblies
If there is no PIA, you can request it from the developer or you can create it yourself.
The way to make it is explained on this page.
How to: Generate Primary Interop Assemblies Using Tlbimp.exe
Is OnFinished a property of the app or measure object? If it is, and it returns a value when queried you could use a while loop to wait for that returned value to be a specific value e.g. if that property returns 'Completed' once the process has finished:
while($measure.OnFinished -ne 'Completed')
{
Sleep 5
}
Difficult to be more specific with my answer as I am not familiar with your COM object :)

Simulating a Mouse Click in Powershell

I already know Powershell is not really meant for GUI automation, but just the same I have a pretty large Powershell script that needs to perform a single GUI operation, that being a left mouse click. I have searched for hours and have not found a satisfactory solution. The closest I have found is an add on called Wasp, but it was written in 2009 and appears to be incomplete anyway.
Is there another add in available to solve this problem?
I cannot condone using this as a first resort, but it should work. Generally when dealing with web pages you want to use URL parameters as much as possible since webpage elements are volatile.
With that said you should be able to create an IE comobject and then select the element that way. For example:
First create an IE object:
$ie = New-Object -ComObject "InternetExplorer.Application"
$ie.navigate("YourPageURLHere.com")
$ie.visible = $true
You can manipulate certain elements by ID (ex: name="username") or even type. These can be easily found be viewing the source code of a webpage. Here are a few examples:
$Username = $ie.document.getElementByID("Username")
$Username.value = $UsernameValue
$SearchButton = $ie.Document.getElementsByTagName("button")
$SearchButton.click()
Even if the webpage changes, since we have it all attached to the IE object you can then grab the output elements that generate after the submit button is clicked and feed them back into your script.

Powershell automation, email MS-Access Query

At an impasse, (a complete loss as to where to go next)
I am building a powershell script to automate a number of manual tasks one of which is to run a query within access and then email that object to a number of recipients.
The closest I have got to was running
$Acc = New-Object -com Access.Application
$Acc.OpenCurrentDataBase("L:\Operations Database\OPS\OPS-V2.0.accdb")
##Test email object
$Acc.DoCmd.RunMacro("EmailLiveFNZ")
This ran the macro that I had produced in Access but I was then required to manually click on an Outlook warning box so it has not resolved the issues.
I have then started playing around with various versions of the following script but can't get it to work.
$Acc = New-Object -com Access.Application
$Acc.OpenCurrentDataBase("L:\Operations Database\OPS\OPS-V2.0.accdb")
##Test email object
$Acc.DoCmd.SendObject acSendQuery, "LiveFNZFundXfer", acFormatXLS, _
"email#address.com", , , _
"Live Transfers", , False
I am assuming that I can send the query out using powershell automatically I just can't find the assistance I need online...
Alternatively if anyone knows how to save an access object to a specific folder location on a PC I could have the script email the file from there, I can't work it out...
Thanks for your help!
Regards
R
I also tried;
$Acc = New-Object -com Access.Application
$Acc.OpenCurrentDataBase("L:\Operations Database\OPS\OPS-V2.0.accdb")
##Test export object
$Acc.DoCmd.OpenQuery("LiveFNZFundXfer") | Export-CSV "C:\LiveFNZFundXfer.csv"
This compiles without errors but does not export anything

Invoke verb on multiple files via Shell.Application

I'm using "Shell.Application" COM object for some automation via PowerShell and I'm stuck on situation where I need to invoke verb on multiple items in folder. Basically I need to simulate situation where user selects multiple files/folders and calls verb from shell menu.
I can do it without any problem on single item, but I haven't found method how to call it on multiple items. Any idea how to do it?
Edit:
This is how I call it on single item:
$shell = New-Object -Com "Shell.Application"
$shell.Namespace($Path).Self.InvokeVerb("some action")
You can use InvokeVerbEx to execute on all files in a folder:
$shell.Namespace("C:\test").Items().InvokeVerbEx()
For particular files in a folder, I would think the best way is to put the single item code that you have in a loop:
$path1, $path2 | %{ $shell.Namespace($_).Self.InvokeVerb() }
The Filter method may be of use too

Powershell script: read an AD attribute and set is an environment variable

I have a problem with some old apps and I need to set an environment variable from AD (hurray)
I'm quite new to PS scripting, so I can use some help.
In my AD I have filled the attribute departmentNumber with information, that part works fine.
Now I need to create a logon script which reads this field from the current user (attribute: departmentNumber, derived from: inetOrgPersonUser) and set this as an environment variable called AFDELING.
I know this can be done using a VB script, but I prefer PS. Can anyone help me with this one?
Thanks in advance for your help,
Peter
Working with environment variables in PowerShell involves the special variable $Env and unfortunately you need to use a .NET method to set environment variables as no cmdlet exists (at least as of v2):
[Environment]::SetEnvironmentVariable("AFDELING", "DeptNo", "User")
The first string parameter is the variable name, the second is the value and the third is basically the persistance level requested for the variable: Machine, User or Process - both machine and user will survive a reboot and future applications will have access to them, though you will need to be running PowerShell with an administrative account to modify the machine-level variables.
Getting the user info should be equally easy. There are a variety of ways that you can access Active Directory, though one of the simplest in your case would be to use the System.DirectoryServices.DirectoryEntry class:
$de = New-Object System.DirectoryServices.DirectoryEntry
$DeptNo = $de.Properties["departmentNumber"]
That should query the current user record from a domain controller, and assign the value from the departmentNumber attribute to the $DeptNo variable. You can then just pop that variable into the second parameter from the first example.