Apologies, I'm incredibly new to PowerShell (And scripting in general), and I'm having a problem with the very basics of IE Automation that I can't quite get my head round.
What I want to do is have a script that automatically logs onto a webpage, and then inputs data into a form. But I can't seem to input data into the text input fields on the login page. I've been scouring the internet left right and centre, but haven't yet found the answer, though I imagine it will be an obvious one.
Here is my script so far:
$ie = new-object -ComObject InternetExplorer.Application;
$requestUri = "www.testurl.com"
$ie.visible = $true
$ie.navigate($requestUri)
while ($ie.ReadyState -ne 4)
{
start-sleep -Seconds 1;
}
$doc = $ie.Document
$doc.GetElementById("ppm_login_username") = $userName
$userName.value = "UserName"
However, whenever I run the script, I get the error
The property 'value' cannot be found on this object. Verify that the property exists and can be set.
+ $userName.value = "UserName"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
I have no experience with a lot of this, so again, apologies for using incorrect terminology.
Using the DOM explorer, the input field has the following line of code:
<INPUT id=ppm_login_username maxLength=240 size=40 name=userName>
So I'm confident that I'm getting the correct object, but it doesn't seem to accept the 'value' method when trying to pass data through to it.
Value does show up as a property of the object though, so I can't understand why it doesn't pass through.
Any help and time you can offer is greatly appreciated!
You've mixed it up. It should be $variable = value. Try:
$doc = $ie.Document
#Set $username to reference of "ppm_logon_username"-input node
$userName = $doc.GetElementById("ppm_login_username")
$userName.value = "UserName"
Where is the variable $userName defined?
It needs to have the property "value".
Usually you could add it like this:
$Username | Add-Member -MemberType NoteProperty -Value "UserName" -Name value
but I am not sure whether this is possible for a variable of the type string.
I am not sure why you are trying to set $userName.value = "UserName" anyway.
Additionally it might be better to just use Invoke-WebRequest / Invoke-RestMethod, instead of trying to automate IE :)
https://technet.microsoft.com/de-de/library/hh849901.aspx
https://technet.microsoft.com/en-us/library/hh849971(v=wps.620).aspx
Related
**Problem I am trying to solve: **
We want to be notified whenever one of our kiosk machines restart due to a Windows Update, so we can remotely connect right away and reset them to the desired state.
After trying different options (i.e. send email via SMTP triggered by an event via Task Scheduler, which proved unreliable due to script taking too long before restart occurs), this is the next attempted solution (perhaps it occurs faster?).
**Current solution attempted: **
Write data to a GoogleSheet via PowerShell script (below), triggered via Task Scheduler when a specific event occurs (i.e. Event Id: 1074). From there, GoogleSheet can easily send us the notification we want using Apps Script (details not relevant for this post).
Import-Module UMN-Google
# Set security protocol to TLS 1.2 to avoid TLS errors
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Google API Authozation
$scope = "https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file"
$certPath = "C:/Scripts/GoogleService/my-cert-path.p12"
$iss = 'name#projectname.iam.gserviceaccount.com'
$certPswd = 'mypassword'
try {
$accessToken = Get-GOAuthTokenService -scope $scope -certPath $certPath -certPswd $certPswd -iss $iss
} catch {
$err = $_.Exception
$err | Select-Object -Property *
"Response: "
$err.Response
}
$accessToken
# Define the GoogleSheet and the target Sheet
$spreadSheetID = 'google-sheet-id-i-omitted-from-this-sample'
$sheetName = 'MachineActivityData'
$EventId = 1074
$A = Get-WinEvent -MaxEvents 1 -FilterHashTable #{Logname = "System" ; ID = $EventId }
$Message = $A.Message
$EventID = $A.Id
$MachineName = $A.MachineName
$Source = $A.ProviderName
# Set the arrayValues
$arrayValues = #($MachineName, $Source, $EventId)
$appendValue = 'Append'
# Write to GoogleSheet (appending data)
Set-GSheetData -accessToken $accessToken -append $appendValue -sheetName $sheetName -spreadSheetID $spreadSheetID -values $arrayValues
Issue encontered:
When running the above script, I get the following error:
Set-GSheetData : A positional parameter cannot be found that accepts argument 'Append'.
At C:\Scripts\script_GoogleSheetConnection.ps1:40 char:1
+ Set-GSheetData -accessToken $accessToken -append $appendValue -sheetN ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-GSheetData], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Set-GSheetData
As you can see, I am using UMN-Google. This documentation helps, but I couldn't find much more than this to help with this error.
This error has something to do with the -append value not being correct.
Per the linked documentation, it appears to be a string (as in the example, and function definition). But I tried other options as well (i.e. bool...).
Any idea why the function Set-GSheetData is not accepting this parameter?
Quick note, I am fairly new to using PowerShell. I appreciate any suggestions.
Thank you kindly,
I tried the above script, and expected data to be appended to the specified GoogleSheet. However, the function Set-GSheetData returned an error, as a parameter is invalid. Per documentation, the parameter I entered is correct.
I am trying to automate checking tenant names using the o365.rock website. I want to enter the tenant name and click the button. however I keep getting errors when trying to put the data in the field.
My test code is:-
$site = "https://o365.rocks"
Start-Process "chrome.exe" $site
while ($site.Busy -eq $true){Start-Sleep -seconds 1;}
$input = $site.Document.getElementByID("INPUT");
$input.value = "testing";
I keep getting this error
You cannot call a method on a null-valued expression. At line:4 char:1
$input = $site.Document.getElementByID("INPUT");
I have inspected the elements and the field only has a tagname of "INPUT". The name & ID fields are blank.
Can anyone suggest what I am doing wrong or how else to do this?
You need to give the field ID name because you are using
site.Document.getElementByID
which is looking at the ID part of the field.
Or better use
$tag_name = document.getElementsByTagName("INPUT");
You can check for the availability of an Office 365 tenant name using the following code:
$TenantName = "contoso"
$URI = "https://tenantchecker.easy365manager.com/api/CheckTenantName/" + $TenantName
(Invoke-WebRequest -Uri $URI -Method GET -ContentType 'application/json').Content | ConvertFrom-Json
(source info: https://www.easy365manager.com/tenant-availability-checker/)
I'm trying to write a script that checks my current public IP address to one that I've written in to see if it has changed. So far I've got this:
$NIP = "97.121.63.227"
$url = "http://checkip.dyndns.com"
$webclient = New-Object System.Net.WebClient
$Ip = $webclient.DownloadString($url)
$Ip2 = $Ip.ToString()
$ip3 = $Ip2.Split(" ")
$ip4 = $ip3[5]
$ip5 = $ip4.replace("</body>","")
$FinalIPAddress = $ip5.replace("</html>","")
$Prod = $NIP.CompareTo($FinalIPAddress)
$Prod
Whenever I run it though, comes up
Missing property name after reference operator.
At line:1 char:17
Pretty new to PowerShell and have no idea what I'm doing wrong
maybe you could use a regex to avoid multiple split and replace :
$NIP = "97.121.63.227"
$url = "http://checkip.dyndns.com"
$webclient = New-Object System.Net.WebClient
$Ip = $webclient.DownloadString($url)
$FinalIPAddress=[regex]::match($ip,"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b").Value
$NIP -eq $FinalIPAddress
I was not able to reproduce the error unfortunately. Perhaps set a breakpoint (F9) at the top line and step through (F10) the script to narrow in on the cause. The error message is pointing to line 1...did you include that line in your example?
I am trying to use InsertAdjacentHtml with IE COM by Powershell but my code fails what can be the reason ?
$oIE = new-object -ComObject InternetExplorer.Application
$oIE.visible=$True
$oIE.navigate2("http://www.quirksmode.org/dom/core/getElementsByName.html")
While ($ie.Busy) {
Sleep 2
}
$doc = $oIE.Document
$btns = $doc.getElementsByTagName("input")
$btns.insertAdjacentHTML('afterend', '<div id="secondDiv">Second</div>');
$oIE.visible=$True
The comand line shows Invalid Operation error
I ran your script both line by line and by saving it as a PowerShell script, but got different results - both were errors.
When running line by line, I get this error:
Method invocation failed because [System.__ComObject] does not contain a method named 'insertAdjacentHTML'.
At line:1 char:1
+ $btns.insertAdjacentHTML('afterend', '<div id="secondDiv">Second</div>');
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (insertAdjacentHTML:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Altough the method 'insertAdjacentHTML' is listed with Get-Member, it cannot be used.
So, I wanted to find a reason for that or another way to achieve the same thing. I ended up with this conclusion: PowerShell might not be the best tool to achieve what you are trying for OR you should use objects that have more reliable methods.
When I run an altered script, line by line, it sort of works:
$oIE = new-object -ComObject InternetExplorer.Application
$oIE.visible=$True
$oIE.navigate2("http://www.quirksmode.org/dom/core/getElementsByName.html")
$doc = $oIE.Document
$btn = $doc.all.item("test", 1)
$btn.insertAdjacentHTML('afterend', '<div id="secondDiv">Second</div>')
$oIE.visible=$True
This is the HTML produced:
<div id="test">
<p name="test">This is a paragraph with name="test"</p>
<ppk name="test">This is a ppk tag with name="test"</ppk>
<p><input name="test"><div id="secondDiv">Second</div>This is an input with name="test"</p>
<p><img name="test">This is an image with name="test"</p>
</div>
To make things even stranger, this only works in a normal PowerShell console, it fails when using PowerShell ISE.
EDIT: Try it with a ForEach loop, it just might work. It occurred to me that you cannot run a method on an array of objects unless you call it within a loop AND another thing, that the page the script was navigating to might have issues.
So, this works:
$oIE = new-object -ComObject InternetExplorer.Application
$oIE.visible = $True
$oIE.navigate2("https://stackoverflow.com/questions/28650033/use-insertadjacenthtml-by-powershell-with-ie-com/")
Start-Sleep -Milliseconds 3333
$doc = $oIE.Document
$btns = $doc.getElementsByName("_id_")
$btns | ForEach-Object { $_.insertAdjacentHTML('afterend', '<div id="secondDiv">Second</div>') }
Thank you for the question, this is nice to know.
I'm working with automating the opening of a public folder by EntryID from IE with javascript and activex and ran across some errors. To debug I've re-wrote it as a power shell script.
$eid = "HEX EntryID FOR PUBLIC FOLDER";
$o = new-object -com outlook.application;
$ns = $o.GetNamespace("MAPI");
#$ns #if this line is commented, error
$f = $ns.GetFolderFromID($eid)
$f.Display();
If I shut outlook down completely, and then run the script I get the following error
Exception calling "GetFolderFromID" with "2" argument(s): "The messaging interface has returned an unknown error. If the problem persists, restart Outlook."
At G:\scripts\outlook.ps1:5 char:25
+ $f = $ns.GetFolderFromID <<<< ($eid)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
If I uncomment the $ns line, everything works fine, even if its removed again. That is, until I close out of Outlook completely, almost as if the $ns com object isn't being truly initialized until I output it to the console.
I'd like to know:
why calling $ns fixes the problem
why powershell thinks I'm passing 2 arguments
is there a way to implement this workaround
in javascript
The GetFolderFromID() requires two arguments: EntryID and StoreID of folder wanted.
This code gives no error and show outlook with PublicFolder selected:
$o = new-object -com outlook.application;
$ns = $o.GetNamespace("MAPI");
$cp = $ns.Folders # FolderClass ComObject containing all Outlook folders, usually first is the PublicFolder
$f = $ns.GetFolderFromID( $cp.GetFirst().EntryID ,$cp.GetFirst().StoreID )
$f.Display();
Using your code I can't do it, $ns line commented or not.
You can get the public folders store programatically:
$ol = New-Object -ComObject Outlook.Application
$pf = $ol.GetNamespace("MAPI").Folders | Where-Object {$_.FolderPath -like "\\Public Folders*"}
$pf.Display()