powershell auto login script not working - shell

This is my url
https://webmail.fasttrackteam.com/Login.aspx
I am able to open this path in IE.
but unable to set loginid & password.
Also dont know how to fire click event.
following is code that I have tried.
$ie = New-Object -com InternetExplorer.Application
$ie.Navigate("https://webmail.fasttrackteam.com/Login.aspx")
$ie.visible = $true
$doc = $ie.document
$user = $doc.getElementById("ctl00_MPH_txtUserName")
$password = $doc.getElementById("ctl00_MPH_txtPassword")
$submit = $doc.getElementById("ctl00_MPH_btnEnterClick")
$user.value = "emailid"
$password.value = "password"
$submit.Click();
$ie.Quit();
$ie.Document.body | Out-File -FilePath C:\Users\amol.kshirsagar\Documents\FastTrack\Work\Extra\AutoLogin\log.txt
EDIT
This is error that I am getting,
You cannot call a method on a null-valued expression.

You call the Quit() method before accessing the Document.body member. As the Quit() call, well, quits the application, don't you think it should be somewhat peculiar to access its data afterwards?
Try accessing the member first, then quitting the browser instance.

Related

powershell script creates Windows 10 notification and it disappears after popup

the following powershell script successfully creates a notification but after the little popup retracts it doesn't show on the Notification Center, any way to leave it in the notification center until the user dismisses it ?
param([String]$prodName)
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
[Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] > $null
$ToastTemplate = '
<toast launch="app-defined-string">
<visual>
<binding template="ToastGeneric">
<text>'+$prodName+'</text>
</binding>
</visual>
</toast>'
Write-Output $ToastTemplate;
$currTime = (Get-Date).AddSeconds(10);
"currTime : " + $currTime
$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
$xml.LoadXml($toastXml.OuterXml)
$schedNotification = New-Object Windows.UI.Notifications.ToastNotification($xml)
$schedNotification.SuppressPopup = $True
$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($prodName)
$notifier.Show($schedNotification)
$schedNotification = New-Object Windows.UI.Notifications.ScheduledToastNotification($xml, $currTime)
$notifier.AddToSchedule($schedNotification)
If you show your notification like this:
CreateToastNotifier("PowerShellAppId")
Then in your "Settings \ System \ Notifications & Actions", there should register new app named "PowerShellAppId".
Edit it, and select option "Show notifications in action center". If you run your script again, message should leave in notification panel.
In your example you have $prodName as AppID. So each time, you run script with different prodName, Windows will register it as separate entry, and you will have to set registry flag ("Show notifications in action center") again.
You can do it using PowerShell like this:
Set-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings\$prodName" -Name "ShowInActionCenter" -Type Dword -Value "1"
Consider using constant app name, something like NotificationManager to simplify things.

which class or method to use from windows forms namespace to show the name of running script using powershell in a form class

I have a powershell script which calls for a progress bar in a form showing execution of some batch files. Which class or method should be used from windows forms namespace to show the name of running batch script using powershell in a form class.
In the code below, in installationScriptsHome folder there are bunch of batch and vbs files, while those scripts are being called i want to show the name of the running script over the progress bar to show which script is running or may be some customised name\message with each script.
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
$ScriptsHome = Get-Item 'c:\installationScriptsHome\*'
# Init Form
$Form = New-Object System.Windows.Forms.Form
$Form.width = 1000
$Form.height = 200
$Form.Text = "**OSP Installation in Progress**"
# Init ProgressBar
$ProgressBar = New-Object System.Windows.Forms.ProgressBar
$ProgressBar.Maximum = $ScriptsHome.Count
$ProgressBar.Minimum = 0
$ProgressBar.Location = new-object System.Drawing.Size(10,70)
$ProgressBar.size = new-object System.Drawing.Size(967,10)
$Form.Controls.Add($ProgressBar)
# Add_Shown action
$ShownFormAction = {
$Form.Activate()
foreach ($b in $ScriptsHome) {
$ProgressBar.Increment(1)
Start-Process $b.FullName -Wait -WindowStyle Hidden
}
$Form.Dispose()
}
$Form.Add_Shown($ShownFormAction)
# Show Form
$Form.ShowDialog()
Thanks in advance.
Use the Label class (MSDN page).
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Point(140,20)
$Label.Size = New-Object System.Drawing.Size(280,20)
# put this in the foreach ($b in $ScriptsHome) { loop
$Label.Text = "$($b.Name)"
Useful link: MSDN System.Windows.Forms NameSpace

How to enter text into an input field through Power Shell?

Here is a PowerShell script to trigger Internet Explorer, open LinkedIn login page and enter some text in the username text field.
$ie = New-Object -Com "InternetExplorer.Application"
$ie.Navigate("www.linkedIn.com")
$ie.Visible = $true
$doc = $ie.document
$usernameElement = $doc.getElementByTagName("input") | Where-Object {$_.id = "session_key-login""}
$usernameElement.Click()
Get-Process iexplore | Foreach-Object {$_.CloseMainWindow()}
Unfortunately, I keep getting the following error:
You cannot call a method on a null-valued expression.
At C:\Users\Pinku\Desktop\Untitled1.ps1:7 char:23
+ $usernameElement.Click <<<< ()
+ CategoryInfo : InvalidOperation: (Click:String) [], RuntimeExcepti
on
+ FullyQualifiedErrorId : InvokeMethodOnNull
I have tried but have not been able to alleviate myself from this issue.Please suggest!
Instead of using $doc.getElementsByTagName("input") and then trying to filter through the results, try retrieving the ID directly using getElementById:
$usernameElement = $doc.getElementById("session_key-login")
$usernameElement.Click()
---Edit---
Response to still getting the null-valued expression after using the above:
The error message is that it can't find any elements called "session_key-login", and so it returns $null, and hence, when you try to invoke the Click() method, it throws the error. Some things to try:
-Check to see if the id exists. Run the following code after creating your $ie object, and see if there is an ID that matches "session_key-login":
$ie = New-Object -Com "InternetExplorer.Application"
$ie.Navigate("www.linkedIn.com")
$ie.Visible = $true
$doc = $ie.document
$doc.getElementsByTagName("Input") | Select Id, Name
-Try running your PowerShell session as Administrator. I know I wasn't able to launch IE properly until I ran PowerShell as Administrator. For ex. even though the iexplore process was created, the physical Internet Explorer window didn't open for me.

PowerShell folder permission error - Some or all identity references could not be translated

I am running this script as Admin and It does create the folders requred, just does not set the appropriate permissions.
$Users = Get-Content "D:\New_Users.txt"
ForEach ($user in $users)
{
$newPath = Join-Path "F:\Users" -childpath $user
New-Item $newPath -type directory
$UserObj = New-Object System.Security.Principal.NTAccount("DOMAIN",$user)
$acl = Get-Acl $newpath
$acl.SetAccessRuleProtection($True, $False)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("O1OAK\$user","AppendData,CreateDirectories,CreateFiles,DeleteSubdirectoriesAndFiles,ExecuteFile,ListDirectory,Modify,Read,ReadAndExecute,ReadAttributes,ReadData,ReadExtendedAttributes,ReadPermissions,Synchronize,Traverse,Write,WriteAttributes,WriteData,WriteExtendedAttributes","ContainerInherit, ObjectInherit","None","Allow")
$acl.SetAccessRule($accessRule)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM","FullControl","ContainerInherit, ObjectInherit","None","Allow")
$acl.SetAccessRule($accessRule)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators","FullControl","ContainerInherit, ObjectInherit","None","Allow")
$acl.SetAccessRule($accessRule)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("1OAK\$user","Delete","ContainerInherit, ObjectInherit","None","Allow")
$acl.removeAccessRule($accessRule)
$acl.SetOwner($UserObj)
$acl | Set-Acl $newpath
}
The first error in a string of 3 that I get is below. I think it is the most important and will fix the other 2.
Exception calling "SetAccessRule" with "1" argument(s): "Some or all identity references could not be translated."
At D:\DOMAIN\IT\IT Private\User Drives\user_folders.ps1:12 char:20
+ $acl.SetAccessRule <<<< ($accessRule)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
The error is pretty self explanatory: Some or all identity references could not be translated.
This means the account couldn't be found. So what you have to do is verify your accounts. Since you're adding 4 ACE's, you'll need to identify which is invalid.
The easiest way to do this is to debug through, line by line using the ISE or PowerGUI.
I tried your code with "NT AUTHORITY\SYSTEM" and "BUILTIN\Administrators" and it works so the issue is with "O1OAK\$user" or "1OAK\$user". You likely have an invalid account in your text file.
a gotch with the user ID is that AD truncates the username, so a user with a long name "j_reallylongname" will have a samid (Security Account Manager (SAM) account name) which is truncated. (j_reallylong)
so when fetching usernames, make sure you verify against the AD before using it.
When i've got the upns, so i run a dsget query to get the samid then use that to build the identity reference.
Adding this in case any C#/ASP.NET developers get this (which is my scenario, and I found this post).
I am using .NET Core in a corporate environment, and I need to check UserGroups as part of security. The code is like (where "user" is a ClaimsPrincipal):
var windowsIdentity = user.Identity as WindowsIdentity;
if( windowsIdentity is null )
throw new Exception( $"Invalid Windows Identity {user.Identity.Name}" );
return windowsIdentity.Groups
.Select( g => g.Translate( typeof( NTAccount ) ).Value );
Anyway, someone in charge of groups deleted a group I was part of, and the AD replication lag caused me to get the error in the title. A logoff and/or reboot worked just fine.
For me it was a case of where i verified whether the script execution knew the password by using $user = Get-Credential "username". i had to turn my $user into $user.UserName To give the script parameters the value they were expecting

Dismiss a Powershell form controlled by a start-job task

I've been tasked with building a powershell script with a GUI which enables users to install network printers. I've succesfully managed to do so, but I cannot meet the requirement that the user be shown a 'please wait' window whilst the printers install. If I switch to the window from the main thread, the GUI hangs. If I move showing the window to a seperate job, I'm never able to close the window again. Here's my attempt:
$waitForm = New-Object 'System.Windows.Forms.Form'
$CloseButton_Click={
# open "please wait form"
Start-Job -Name waitJob -ScriptBlock $callWork -ArgumentList $waitForm
#perform long-running (duration unknown) task of adding several network printers here
$max = 5
foreach ($i in $(1..$max)){
sleep 1 # lock up the thread for a second at a time
}
# close the wait form - doesn't work. neither does remove-job
$waitForm.Close()
Remove-Job -Name waitJob -Force
}
$callWork ={
param $waitForm
[void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
$waitForm = New-Object 'System.Windows.Forms.Form'
$labelInstallingPrintersPl = New-Object 'System.Windows.Forms.Label'
$waitForm.Controls.Add($labelInstallingPrintersPl)
$waitForm.ClientSize = '502, 103'
$labelInstallingPrintersPl.Location = '25, 28'
$labelInstallingPrintersPl.Text = "Installing printers - please wait..."
$waitForm.ShowDialog($this)
}
Does anyone know how I can dismiss the $waitForm window when the long-running task has concluded?
You could try to run the Windows Forms dialog on the main thread and do the actual work in a background job:
Add-Type -Assembly System.Windows.Forms
$waitForm = New-Object 'System.Windows.Forms.Form'
$labelInstallingPrintersPl = New-Object 'System.Windows.Forms.Label'
$waitForm.Controls.Add($labelInstallingPrintersPl)
$waitForm.ClientSize = '502, 103'
$labelInstallingPrintersPl.Location = '25, 28'
$labelInstallingPrintersPl.Text = "Installing printers - please wait..."
$waitForm.ShowDialog($this)
Start-Job -ScriptBlock $addPrinters | Wait-Job
$waitForm.Close()
$addPrinters = {
$max = 5
foreach ($i in $(1..$max)) {
sleep 1 # lock up the thread for a second at a time
}
}
This first answer was correct, create the form on the main thread and perform the long running task on a separate thread. The reason it doesn't execute the main code until after the form is dismissed is because you're using the 'ShowDialog' method of the form, this method haults subsequent code execution until the form is closed.
Instead use the 'show' method, code execution will continue, you should probably include some event handlers to dispose of the form
Add-Type -Assembly System.Windows.Forms
$waitForm = New-Object 'System.Windows.Forms.Form'
$labelInstallingPrintersPl = New-Object 'System.Windows.Forms.Label'
$waitForm.Controls.Add($labelInstallingPrintersPl)
$waitForm.ClientSize = '502, 103'
$labelInstallingPrintersPl.Location = '25, 28'
$labelInstallingPrintersPl.Text = "Installing printers - please wait..."
$waitForm.Add_FormClosed({
$labelInstallingPrintersPl.Dispose()
$waitForm.Dispose()
})
$waitForm.Show($this)
Start-Job -ScriptBlock $addPrinters | Wait-Job
$waitForm.Close()
$addPrinters = {
$max = 5
foreach ($i in $(1..$max)) {
sleep 1 # lock up the thread for a second at a time
}
}
How about adding a Windows.Forms.Progressbar to the main GUI window? Update its value step by step when adding printers, so users will see that the application is working.

Resources