how to bring forward an IE window with powershell - powershell

I have the following powershell command that will run on users pc on a scheduled basis, based on a REST API Call to know if they havent submitted the timesheet.
It works fine, but I would like to put the IE window as the main window at that moment.
$msgBoxInput = [System.Windows.MessageBox]::Show('You havent submitted the timesheet. Please do it now','xyz is watching you','OK','Error')
$IE=new-object -com internetexplorer.application
$IE.navigate2("www.microsoft.com")
$IE.visible=$true
Is it doable with powershell? in an easy way

It should be doable.
Have a look at this example:
## Find all Active Windows Titles
$windows=Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object MainWindowTitle
## Find Specific name
$WindowTitle=($windows | ? {$_ -match "Internet Explorer"} ).MainWindowTitle
## Add Type and Focus Activate the Window
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate($WindowTitle)
You just have to make sure that you have the correct MainWindowTitle.
Hope it helps

Related

Use PowerShell to check the box to "Remove this item if it is no longer applied" option behavior in Group Policy preferences

I have been exploring using PowerShell to inject a few RegKeys and settings into GPOs and have it pretty much figured out, all except how to check the box for the "Remove this item if it is no longer applied" option behavior in Group Policy preferences. for the life of me, i can't find anything on how to use PowerShell to set that. Can anyone help with this?
its becoming a pain to use PowerShell to inject the Reg Settings into the GPOs that I need and then have to go into each GPO and edit them to check the box for "Remove this item if it is no longer applied" in every singe Reg Key added to the GPOs.
for example here is 2 lines of a 30+ line PowerShell I am using to inject the reg settings and need to add the check box for "Remove this item if it is no longer applied"
$GPO = Read-Host -Prompt 'Enter the GPO Name you want to change'
Set-GPPrefRegistryValue -Name "$GPO" -Context Computer -Action Replace -Order 1 -Key "HKLM\SOFTWARE\Microsoft\.NETFramework" -ValueName "AllowStrongNameBypass" -Value 0 -Type DWord
The GroupPolicy module does not allow these settings to be checked.
The same goes for Item-level targeting etc.
You can use a third party powershell module (sdmsoftware something) to do things like this. They didn't specify the cost for that online so I wrote something that seems to do the trick.
I just put this at the bottom of my Set-GPPrefRegistryValue code, at the end of the script.
Do understand it and evaluate the risk yourself. I haven't had this in production.
$GPO = Get-GPO -Name $GroupPolicyName -Server $DomainController
$domain = (($GPO.path -split ",") | where-object {$_ -like "DC=*"}).replace("DC=","") -join "."
$Path = "\\"+$domain+"\SYSVOL\"+$domain+"\Policies\{"+$gpo.id+"}"+"\Machine\Preferences\Registry\Registry.xml"
#Should amount to something like this - \\domain.test\SYSVOL\domain.test\Policies\{A235F578-35F1-42D9-9CE7-CB0A74F85C08}\Machine\Preferences\Registry\Registry.xml
[xml]$xml = Get-Content $Path
foreach ($regsetting in $xml.registrysettings.registry | where-object {(!($_.removePolicy))}){ #This filter will find any reg entries that do not have "remove this item when it is no longer applied" checked
$regsetting.SetAttribute("removePolicy","1") #then toggle that box
$regsetting.SetAttribute("bypassErrors","1") #Don't know why, but when done in GUI this gets toggled as well.
}
$xml.save($Path)

Close specific Excel file using Powershell

What would be the appropriate PowerShell cmdlet to use to kill a specific Excel file. The command
Stop-Process -Name "excel"
closes all open Excel applications.
Thanks in advance!
Actually, excel opens .xlsx files in one instance of excel.exe
Kill the excel.exe will kill all opening workbooks. The MainWindowTitle only shows the active workbook, so you will not able to match passive workbooks by the property.
A better way to close a specific workbook is to acquire the excel instance by com object.
Close the workbook matched the Name (file name) or FullName (file path)
$excel = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
$excel.DisplayAlerts = $false
$excel.Workbooks | %{if($_.Name -imatch "excel file name"){$_.Close()}}
Try this out:
Get-Process excel –ea 0 | Where-Object { $_.MainWindowTitle –like ‘*report.csv*’ } | Stop-Process
Here's the official guide from MS:
Stop-Process
$Application = New-Object -ComObject excel.application
$Application.Visible=$True
$workbook = $application.Workbooks.open("C:\mySheet.xlsx")
Start-Sleep -Seconds 5
$workbook.close($false)
The problem is that the window remains open while the dokument is closed.
Hope it still helps.
BR

How to avoid powershell going into wait mode automatically

I have a powershell script which automates the upload of a report. After the file upload dialog box opens in Internet Explorer, My code tries to get it's id and then send keys and send the file address and sendkeys enter. But unfortunately as soon as the file upload dialog box pops up my script doesn't proceed further and waits there. If I hit close (in the file upload dialog) then the script continues. Is there any way by which I can tell powershell to not wait for anything?
Here's my code :-
$dummy = get-process iexplore | where {$_.mainWindowTitle -eq "ArkAngelWeb - Hitachi Systems Security Inc. - Internet Explorer"} | select -expand id
Sleep 1
$temp = $ie.Document.documentElement.getElementsByClassName("v-button-caption") | Where-Object {$_.innerHTML -eq "Select file"}
$temp.click()
Sleep 2
$swshell=New-Object -ComObject wscript.shell
$fileUploadDialog = get-process iexplore | where {$_.mainWindowTitle -eq "ArkAngelWeb - Hitachi Systems Security Inc. - Internet Explorer" -and $_.Id -ne
$dummy.Id} | select -expand id
$swshell.AppActivate($fileUploadDialog.Id)
$swshell.SendKeys("H");
$swshell.SendKeys("{TAB}")
$swshell.SendKeys("C:\Users\ratns1\Desktop\TEST_FILE.txt")
$swshell.SendKeys("~")
Thanks
This is the issue with SendKeys, timing, UI controls, etc.
You are popping a model dialog box, and that is what's causing the wait.
By design, your script will not continue until you dismiss it. This is the design for dialogs.
PoSH notwithstanding, it is your use case that is the catch 22, not PoSH itself.
Take a look at the Wasp module to take the load off all the sendkey and Window lookup stuff off your plate.
Occasionally, the only way of automating processes is to send
keystrokes or mouse clicks to UI elements. A good and free PowerShell
extension is called "WASP" and is available here:
http://wasp.codeplex.com/
Once you install the module (do not forget to unblock the ZIP file
before you unpack it, via right-click, Properties, Unblock), the WASP
module provides the following cmdlets:
Get-WindowPosition
Remove-Window
Select-ChildWindow
Select-Control
Select-Window
Send-Click
Send-Keys
Set-WindowsActive
Set-WindwowPosition
Here is a simple automation example using the Windows calculator:
Import-Module WASP
# launch Calculator
$process = Start-Process -FilePath calc -PassThru
$id = $process.Id
Start-Sleep -Seconds 2
$window = Select-Window | Where-Object { $_.ProcessID -eq $id }
# send keys
$window | Send-Keys 123
$window | Send-Keys '{+}'
$window | Send-Keys 999
$window | Send-Keys =
# send CTRL+c
$window | Send-Keys '^c'

FolderItem.Name does return name without file extension

Create file, lets say at C:\randomname\file.txt,
Now run the following script via PowerShell:
$shell = new-object -com shell.application
$folder = $shell.NameSpace("C:\randomname")
$folder.Items() | where {$_.Name -eq "file.txt"}
Observe no output is produced which is rather unexpected.
Any idea how to resolve this situation in a reasonable manner other than modifying Windows settings?
EDIT:
To prevent confusion, this is just a stripped down version of my actual problem. Reason why I am using shell.application and not Get-ChildItem is that my randomname folder is actually zipped, i.e. I have randomname.zip and my actual code looks like this:
$shell = new-object -com shell.application
$zip = $shell.NameSpace("C:\randomname.zip")
$folder = $zip.Items() | where {$_.Name -eq "randomname"}
$folder.GetFolder.Items() | where {$_.Name -eq "file.txt"}
FolderItem.Name return value depends on the value of particular Windows setting. Try the following:
Open Control Panel,
Folder Options, View tab,
Uncheck Hide extensions for known file types.
Re-run the script and you will see the expected output:
Application : System.__ComObject
Parent : System.__ComObject
Name : file.txt
Path : C:\randomname\file.txt
...
I was trying to write a portable script but after finding out how Name works this seems rather hard as I have no control over Windows settings of our customers and there is nothing like FullName for FolderItem so I can't figure out the reliable way out.
EDIT:
Based on suggestion from Nick Sedgewick, that .Path always returns filename with extension, unlike .Name, I was able to create a working workaround which does not depend on Windows settings and looks like this:
$shell = new-object -com shell.application
$folder = $shell.NameSpace("C:\")
$folder.Items() | where {(split-path $_.Path -leaf) -eq "file.txt"}
A Namespace Item has a PATH property, which returns full path and filename for files, and always includes the filename extension, whether the user has 'hide filename extensions' set or not.
So, use 'Path' instead of 'Name' and either write a function to pass $_.Path to which can the extract the filename part, or use an equivalent of the LIKE operator if there is one in powershell

PowerShell get running explorer process and their documents

How can i access document property of already running explorer processes. i am using following line of code to get process.
$ie2 = Get-Process |where {$.mainWindowTItle -eq "Windowtitletext"} | where {$.ID -ne $ieParentProcessNumber}
now i want to do some processing on this processes like $ie2.Document etc.
It seems like you are trying to access the Document (i.e a webpage's data) directly from the process. This is not possible using the get-process.
You would need to create a instance of a IE com object for example or use the System.Net.WebClient if you want to just read data from a web site. Post more info about what you are trying to do and we can possibly help you out better
You can attach to the ie window:
$app = New-Object -ComObject shell.application
$popup = $app.Windows() | where {$_.LocationName -like "*foo*"}
$popup.document
If you know that you'll receive 1 object:
(Get-Process explorer).CPU
If you want to know what are the available properties:
Get-Process explorer | Get-Member
If you have more than one object in your result set (e.g. Get-Process returning mutiple processes mathing search criteria):
Get-Process | Where-Object { $_.Handles -ge 200 } | Foreach-Object { $_.CPU }