$ie = new-object -com internetexplorer.application
$ie.visible=$true
$ie.navigate('https://google.co.in')
while($ie.ReadyState -ne 4)
{
Write-Host "dom is loading"
$ie.ReadyState -eq 4
$ie.ReadyState -eq 3
$ie.ReadyState -eq 2
$ie.ReadyState -eq 1
$ie.ReadyState -eq 0
start-sleep -M 100
}
($ie.Document.Document3_getElementsByTagName('a')|where-object{$_.innerText -eq "मराठी"}).click()
Try to get Admin Access before running script
Use Below Script before running your script. It will Provide you admin access to run your Script
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent();
$myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID);
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator;
if ($myWindowsPrincipal.IsInRole($adminRole))
{
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)";
Clear-Host;
}
else {
$newProcess = New-Object System.Diagnostics.ProcessStartInfo "PowerShell";
$newProcess.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"
$newProcess.Verb = "runas";
[System.Diagnostics.Process]::Start($newProcess);
Exit;
}
this should help you :
$ie = new-object -com internetexplorer.application
$ie.visible=$true
$ie.navigate('https://google.co.in')
while($ie.ReadyState -ne 4)
{ Write-Host "dom is loading" waiting
start-sleep -M 100 }
($ie.Document.IHTMLDocument3_getElementsByTagName('a')|where-object{$_.innerText -eq "मराठी"}).click()
note : when you are running the script second time on ie it will not find the tag because language is already changed
Related
Start-Sleep -Seconds 5
$edge = (New-Object -COM "Shell.Application").Windows()| ? { $_.Name -like "*Microsoft Edge*" }
while(1) {
Start-Sleep -Seconds 10
try{
$edge.Refresh()
} catch { exit }
}
The code below should work. Consider using the Microsoft Edge Driver if you need to do more advanced automation.
$proc = [System.Diagnostics.Process]::Start("msedge.exe", "https://www.stackoverflow.com") | Get-Process
$wshell = New-Object -ComObject WScript.Shell
while ($true) {
Start-Sleep -Seconds 10
$wshell.AppActivate($proc.Id)
$wshell.SendKeys("{F5}")
}
I am trying to run below code to install realtek audio driver on dell laptop but getting below error. Is it possible to use this script for all model laptop to install missing audio driver or update it? Any help would be greatly appreciated
ERROR:
RegistrationState ServiceID IsPendingRegistrationWithAU Service
----------------- --------- --------------------------- -------
3 7971f918-a847-4430-9279-4a52d1efe18d False System.__ComObject
Exception from HRESULT: 0x80240024
+ $Downloader.Download()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
Installing Drivers...
Exception from HRESULT: 0x80240024
+ $InstallationResult = $Installer.Install()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
**CODE:**
$UpdateSvc = New-Object -ComObject Microsoft.Update.ServiceManager
$UpdateSvc.AddService2("7971f918-a847-4430-9279-4a52d1efe18d",7,"")
$Session = New-Object -ComObject Microsoft.Update.Session
$Searcher = $Session.CreateUpdateSearcher()
$Searcher.ServiceID = '7971f918-a847-4430-9279-4a52d1efe18d'
$Searcher.SearchScope = 1 # MachineOnly
$Searcher.ServerSelection = 3 # Third Party
$Criteria = "IsInstalled=0 and Type='Driver'"
Write-Host('Searching Driver-Updates...') -Fore Green
$SearchResult = $Searcher.Search($Criteria)
$Updates = $SearchResult.Updates | Where-Object { $_.DriverManufacturer -like 'Realtek' }
#Show available Drivers...
$Updates | select Title, DriverModel, DriverVerDate, Driverclass, DriverManufacturer | fl
#Download the Drivers from Microsoft
$UpdatesToDownload = New-Object -Com Microsoft.Update.UpdateColl
$updates | % { $UpdatesToDownload.Add($_) | out-null }
Write-Host('Downloading Drivers...') -Fore Green
$UpdateSession = New-Object -Com Microsoft.Update.Session
$Downloader = $UpdateSession.CreateUpdateDownloader()
$Downloader.Updates = $UpdatesToDownload
$Downloader.Download()
#Check if the Drivers are all downloaded and trigger the Installation
$UpdatesToInstall = New-Object -Com Microsoft.Update.UpdateColl
$updates | % { if($_.IsDownloaded) { $UpdatesToInstall.Add($_) | out-null } }
Write-Host('Installing Drivers...') -Fore Green
$Installer = $UpdateSession.CreateUpdateInstaller()
$Installer.Updates = $UpdatesToInstall
$InstallationResult = $Installer.Install()
if($InstallationResult.RebootRequired) {
Write-Host('Reboot required! please reboot now..') -Fore Red
} else { Write-Host('Done..') -Fore Green } ```
There are a couple of things I would change in your code.
For one thing, I think you are (unnecessarily) creating a new Microsoft.Update.UpdateColl object twice. Then you are not checking if there actually are updates to install, at which point the code should exit.
The test for the driver manufacturer in your code is -like 'Realtek', but without wildcard characters (*) surrounding it, this is the same as -eq 'Realtek' and because of that you might miss a couple.
# check if the Windows Update service is running
if ((Get-Service -Name wuauserv).Status -ne "Running") {
Set-Service -Name wuauserv -StartupType Automatic
Start-Service -Name wuauserv
}
# check if there are updates available
$UpdateSession = New-Object -Com Microsoft.Update.Session
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
Write-Host 'Searching Driver-Updates...' -ForegroundColor Green
$SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Driver' and IsHidden=0")
# collect the updates
$UpdateCollection = New-Object -Com Microsoft.Update.UpdateColl
$Updates = for ($i = 0; $i -lt $SearchResult.Updates.Count; $i++) {
$Update = $SearchResult.Updates.Item($i)
# we are only interested in RealTek Audio driver updates
# if you need to add more manufacturers, change the first part in the 'if' to for instance
# $Update.DriverManufacturer -match 'Realtek|Conexant|Intel'
if ($Update.DriverManufacturer -like '*Realtek*' -and
($Update.Title -like '*audio*' -or $Update.Description -like '*audio*')) {
if (-not $Update.EulaAccepted) { $Update.AcceptEula() | Out-Null }
[void]$UpdateCollection.Add($Update)
# output a PsCustomObject for display purposes only
$Update | Select-Object Title, DriverModel, DriverVerDate, Driverclass, DriverManufacturer
}
}
# no updates found; exit the script
if ($null -eq $Updates -or $Updates.Count -eq 0) {
Write-Host 'No Driver-Updates available...' -ForegroundColor Cyan
}
else {
# Show available driver updates...
$Updates | Format-List
# download the updates
Write-Host 'Downloading driver updates...' -ForegroundColor Green
$Downloader = $UpdateSession.CreateUpdateDownloader()
$Downloader.Updates = $UpdateCollection
$Downloader.Priority = 3 # high
[void]$Downloader.Download()
# install the updates
Write-Host 'Installing Drivers...' -ForegroundColor Green
$Installer = $UpdateSession.CreateUpdateInstaller()
# accept all Critical and Security bulletins.
$Installer.ForceQuiet = $true
$Installer.Updates = $UpdateCollection
$InstallationResult = $Installer.Install()
$ResultCode = $InstallationResult.ResultCode
# test if the computer needs rebooting
if ($InstallationResult.RebootRequired) {
Write-Host 'Reboot required! please reboot now..' -ForegroundColor Red
}
else {
Write-Host 'Done..' -ForegroundColor Green
}
}
# Clean-up COM objects
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($UpdateSession)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($UpdateSearcher)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($UpdateCollection)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($SearchResult)
if ($Downloader) { $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Downloader)}
if ($Installer) { $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Installer)}
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
Symantec recently changed their download page which moved to broadcom. Since then Invoke-WebRequest cannot grab the http url for the v5i64.exe file.
However the http url can be found when using Developer Tools in the browser looking at the Elements level, inside the body section of the page.
Does anyone have an idea on how this daily-changed url can be extracted with PowerShell?
$webreq = Invoke-WebRequest "https://www.broadcom.com/support/security-center/definitions/download/detail?gid=sep"
$webreq.Links | Select href
Use IE via ComObject
$ie = new-object -ComObject "InternetExplorer.Application"
$ie.visible=$True
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
$IE.navigate2("https://www.broadcom.com/support/security-center/definitions/download/detail?gid=sep")
while ($IE.busy) {
start-sleep -milliseconds 1000 #wait 1 second interval to load page
}
Then find elementy by $ie.Document.IHTMLDocument3_getElementsByTagName("element name")
The following PowerShell script will prompt you to download the links containing the text v5i64.exe and HTTPS. This works on PowerShell 5.1 for Windows. It does not work for PowerShell 6 or 7 (PowerShell Core).
Tested on Windows 10.0.18363.657, Internet Explorer 11.657.18362, PowerShell 5.1.18362.628
$url = "https://www.broadcom.com/support/security-center/definitions/download/detail?gid=sep"
$outfile = "./v5i64.exe"
$ie = New-Object -ComObject "InternetExplorer.Application"
$ie.visible=$True
while($ie.Busy) {
Start-Sleep -Milliseconds 100
}
$ie.navigate2($url)
while($ie.ReadyState -ne 4 -or $ie.Busy) {
Start-Sleep -milliseconds 500
}
$ie.Document.getElementsByTagName("a") | % {
if ($_.ie8_href -like "*v5i64.exe") {
if ($_.ie8_href -like "https://*") {
$len = (Invoke-WebRequest $_.ie8_href -Method Head).Headers.'Content-Length'
Write-Host "File:" $_.ie8_href
Write-Host "Size:" $len
$confirm = Read-Host "Download file? [y/n]"
if ($confirm -eq "y") {
Write-Host "Downloading" $_.ie8_href
Invoke-WebRequest -Uri $_.ie8_href -OutFile $outfile
}
}
}
}
$ie.Stop()
$ie.Quit()
thanks for the proposed solutions. However here is my final code I am using:
$SEP_last_link = ("http://definitions.symantec.com/defs/"+($SEP_last | Select-String release -NotMatch | select -Last 1))
$Symantec_folder = "C:\Download for DVD\Symantec"
$Symantec_filepath = "$Symantec_folder\$SEP_last"
if (!(Test-Path "$Symantec_filepath" -PathType Leaf)) {
Write-Host "`rStart to download Symantec $SEP_last file: $(Get-Date)`r"
$start_time = (Get-Date)
$webclient = New-Object System.Net.WebClient
$WebClient.DownloadFile($SEP_last_link, $Symantec_filepath)
Write-Host "`r$SEP_last file has been downloaded successfully`r" -ForegroundColor Green
$end_time = $(get-date) - $start_time
$total_time = "{0:HH:mm:ss}" -f ([datetime]$end_time.Ticks)
Write-Host "`rTime to download Symantec $SEP_last file: $total_time`r"
} else {
Write-Host "`rSymantec $SEP_last file already exists!`r" -ForegroundColor Yellow
}
Get-ChildItem -Path "$Symantec_Folder\*-v5i64.exe" -Exclude "$SEP_last" -Verbose –Force | Remove-Item
My case happens when I run $IE.quit() already, but internet explorer still exists in the task manager.
if I run the quit function at "quit IE 1" there, the Internet Explorer will close/end (not exits in Task Manager),
but when I run it at "quit IE 2" there, the IE not end (still exist in Task Manager)
if run with $IE.Visible = $true it has no such problem.
Environment: Windows Server 2016, PowerShell v5.1
May I know what may cause this?
May I know after the "confirm page loaded", what happened to $IE? And possibly cause IE not to quit.
Or how I can trace this kind of problem?
I do try to run this without try/catch, but the same thing happens. I try to put $IE = null, but the same, while, the $IE.Quit() description as to force the end of IE, suppose no wonder what is running on the IE. It will end the task.
Here is the PowerShell script:
$looping = 10
timenowhms = (Get-Date -f HH:mm:ss)
try {
$Url = "http://localhost:8080/commandcenter/checking.aspx"
$IE = New-Object -Com InternetExplorer.Application
$IE.Height = 700
$IE.Width = 750
$IE.Top = 10
$IE.Left = 10
$IE.Visible = $false; # can turn on for testing purpose
$IE.Navigate2($url);
$IEPID = [IntPtr]::Zero
[Win32Api]::GetWindowThreadProcessId($IE.HWND, [ref]$IEPID);
# quit IE 1
$IE.Quit();
} catch {
$timenowhms = (Get-Date -f HH:mm:ss);
echo "$td_date $timenowhms Open website failed";
if ((Get-Process -Name "iexplore*" | ? {$_.Id -eq $IEPID} | measure).Count -eq 1) {
Stop-Process -Id $IEPID -force
};
exit 1
}
# confirm page loaded
while ($ie.Busy -eq $true) {
if ($looping -eq 0) {
$timenowhms = (Get-Date -f HH:mm:ss);
echo "$td_date $timenowhms Timeout, page not show";
if ((Get-Process -Name "iexplore*" | ? {$_.Id -eq $IEPID} | measure).Count -eq 1) {
Stop-Process -Id $IEPID -Force
};
exit 1
} else {
Start-Sleep -Milliseconds 2500;
$looping--;
}
}
# quit IE 2
# $IE.Quit();
exit
We use Citrix in our company and there are two addresses for accessing the Citrix StoreFront:
internal-access.company.com
external-access.company.com
Link 1 only works when they're on the internal network (either locally or on VPN) and link 2 only works when they're not on the internal network. This leaves users to guess at what shortcut on their desktop they need to double click.
In order to resolve the confusion for our end users I have written this little snippet below. It works just as expected but because it depends on PING to see whether an internal server can be reached to decide... the execution is quite slow.
What I would like to do is execute the relevant block as soon as a response is received from a PING, rather than wait for all 4 PING attempts to complete. Is this possible in PowerShell?
So rather than "PING 4 times and if at least 1 response was received run the block" it's "PING 4 times and on first response run block".
if(Test-Connection -Quiet -ComputerName "10.10.10.10" -Count 2){
$url = "http://internal-access.company.com"
$ie = New-Object -com internetexplorer.application;
$ie.visible = $true;
$ie.navigate($url);
}elseif(Test-Connection -Quiet -ComputerName "8.8.8.8" -Count 4){
$url = "https://external-access.company.com"
$ie = New-Object -com internetexplorer.application;
$ie.visible = $true;
$ie.navigate($url);
}else{
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Unable to connect to Citrix. Please check your network connection and call the Service Desk on +44(0)207 111 1111 if you require assistance. Thank you.",0,"No network connection detected!",0x1)
}
Thanks in advance,
Arbiter
This should be a nice solution to your problem:
notice I'm using Start-Process to launch the webpage in the default browser for ease of use.
Function Test-QuickConnection($ip,$count=4,$ttl=50){
$attempts = 0
do{
$connected = Test-Connection $ip -Quiet -Count 1 -TimeToLive ([math]::Ceiling(($ttl/$count)))
} while ((++$attempts -lt $count) -and !$connected)
return $connected
}
if (Test-QuickConnection "10.10.10.10"){
Start-Process "http://internal-access.company.com"
} elseif (Test-QuickConnection "8.8.8.8"){
Start-Process "https://external-access.company.com"
} else {
Add-Type -AssemblyName "System.Windows.Forms"
[System.Windows.Forms.MessageBox]::Show("Unable to connect to Citrix")
}
You can test 4 pings with -Count 1 and break the loop when ping is ok :
for($i = 0; $i -lt 4; $i++){
if(Test-Connection -Quiet -ComputerName "8.8.8.8" -Count 1){
$url = "https://external-access.company.com"
$ie = New-Object -com internetexplorer.application
$ie.visible = $true
$ie.navigate($url)
break
}
}
#Script continues
you can check the status code for the test-connection like:
If( (Test-Connection servername -Count 1).StatusCode -eq 0)
But i would suggest you to check only once in that case . Make the count as 1 like:
Test-Connection -Quiet -ComputerName "8.8.8.8" -Count 1