PowerShell to Open Outlook, Make Visible - powershell

My mission is to graduate from using PowerShell to create an instance of Outlook to simply viewing, or making visible the process that I can see in the TaskManager.
To Digress, this works for Word.Application
but not for Outlook.Application.
$MsApp = New-Object -comObject Word.Application
$MsApp.Visible = $true
I have checked the methods but cannot find a suitable verb to open, run or make visible.
I would be so grateful for a solution.

To activate a running Outlook that's just minimized:
[Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application").ActiveWindow().Activate()
To create an Outlook instance that's visible (it's simplest to just start outlook.exe):
(new-object -com Outlook.Application).GetNamespace("MAPI").GetDefaultFolder("olFolderInbox").GetExplorer().Display()
To make the code clearer:
$outlook = new-object -com Outlook.Application
$namespace = $outlook.GetNamespace("MAPI")
$folder = $namespace.GetDefaultFolder("olFolderInbox")
$explorer = $folder.GetExplorer()
$explorer.Display()

If you want to make visible an already running instance of Word or Outlook, you don't want to use New-Object. You want to get the running object. You can do this with a .NET call:
$word = [Runtime.InteropServices.Marshal]::GetActiveObject("Word.Application")
$word.Visible = $true

Related

Powershell, Outlook hidden mailbox management.

anyone have any idea what I may need to change. I have the code below that works fine. But recently I've decided to hide the mailbox from the address book. This has cause the below script to stop working.. If I unhide the mailbox it works again. But I would prefer to keep it hidden.
quick description of what it does.
it gets a shared mailbox then a specific folder in the inbox folder and then gets all the emails in that folder.
$Outlook = New-Object -comobject Outlook.Application
$namespace = $Outlook.GetNameSpace("MAPI")
$olRecipient = $namespace.CreateRecipient("sharedmailbox#mail.com")
$SInbox = $namespace.GetSharedDefaultFolder($olRecipient,"6")
$targetFolder = $SInbox.Folders('targetfolder')
$Completedfolder = $targetFolder.Folders("Complete")
$Emails = #()
$Emails = $targetfolder.Items
The recipient created by CreateRecipient cannot be resolved if the user is hidden from GAL. And if it cannot be resolved, GetSharedDefaultFolder will not work either.

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 +","
}

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

Multiple Actions for one Outlook rule in Powershell

I have a question about Outlook Rules in Powershell. I wrote some code that successfully stores any incoming e-mail from a certain sender to the deleted-items folder. I did this because when the mails enter the junk folder, the junk folder still has the counter token of mails, so in the end it will say I have 10-mails in the junk folder.
I want to avoid this by just throwing the incoming mails from that sender to the deleted-items folder and also marking the mail as "read" so that I don't see the clutter in the deleted items folder.
The question is really:
Can I add multiple actions to the same outlook rule in powershell? if so, how?
What is the syntax / code for the "run script" action?
My code so far:
$ol = New-Object -ComObject Outlook.Application
$ns = $ol.GetNamespace("MAPI")
$olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders"
$outlook = New-Object -ComObject outlook.application
$namespace = $Outlook.GetNameSpace("MAPI")
$inBox = $ns.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)
$deleted = $ns.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderDeletedItems)
$rules = $outlook.session.DefaultStore.GetRules()
$rule = $rules.create("Move mail: to DeletedItems", [Microsoft.Office.Interop.Outlook.OlRuleType]::olRuleReceive)
$rule_Address = $rule.Conditions.SenderAddress
$rule_Address.Enabled = $true
$rule_Address.Address = #("<Sender Address>")
$action = $rule.Actions.MoveToFolder
$action.Enabled = $true
[Microsoft.Office.Interop.Outlook._MoveOrCopyRuleAction].InvokeMember("Folder",[System.Reflection.BindingFlags]::SetProperty,$null, $action, $deleted)
$rules.Save()
This code works so far.
Please help.
Thanks!
Can I add multiple actions to the same outlook rule in powershell? if so, how?
Took a bit but I got a working test that uses multiple actions applied to a single rule. It is actually easy and you just need to repeat the steps you have already done and create a different action variable.
In my example, just showing the end of the code, I have added a action to display a message in the New Item Alert window.
...
$action = $rule.Actions.MoveToFolder
$action.Enabled = $true
$anotherAction = $rule.Actions.NewItemAlert
$anotherAction.Text = "I am awesome!"
$anotherAction.Enabled = $true
[Microsoft.Office.Interop.Outlook._MoveOrCopyRuleAction].InvokeMember("Folder",[System.Reflection.BindingFlags]::SetProperty,$null, $action, $deleted)
$rules.Save()
You quite possibly already tried something like this. If not there is an important reference for this that you need to be aware of.
What is the syntax / code for the "run script" action?
This is one of the actions you cannot programatically set as per this reference for Office 2007 or this one for Office 2010/2013. The tables are similar and rather large to include here but I will reference the one in your 2nd bullet.
Action : Start a script
Constant in olRuleActionType : olRuleActionRunScript
Supported when creating new rules programmatically? : No
Apply to olRuleReceive rules? : Yes
Apply to olRuleSend rules? : No
There are others as well where you are restricted. So you need to keep that in mind when you are making your rules.

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 {...}