Powershell Handling cookie popup without using invoke-webrequest - powershell

I am attempting to get a script working that does not use invoke-webrequest. The problem I am having is that when I run the script a popup prompt occurs, the popup consists of the following message;
"Windows Security Warning
To allow this website to provide information personalized for you, will you allow it to put a small file (called a cookie) on your computer?"
with yes no response from user
The code I am executing is the following:
$ParsedHTML = New-Object -com "HTMLFILE"
$webresponse = New-Object System.Net.WebClient
$webresponse.Headers.Add("Cookie", $CookieContainer.GetCookieHeader($url))
$result = $webresponse.DownloadString($url)
$ParsedHTML.IHTMLDocument2_write($webresponse)
$ParsedHTML.body.innerText
The main problem with this code is that the $url I am using part of the weblink checks to see if cookies are enabled and this code causes a returned value of disabled.
My question, is there a way to handle the cookie request without changing the output response from the test url site.
Note: This script will be automating a process over hundreds of remote computers and thus having an unhandled popup will just prevent the script from running.

I found the answer in another SO question Using Invoke-Webrequest in PowerShell 3.0 spawns a Windows Security Warning
add the parameter -UseBasicParsing
Technet https://technet.microsoft.com/en-us/library/hh849901.aspx notes that the parameter stops the DOM processing. and has the caveat "This parameter is required when Internet Explorer is not installed on the computers, such as on a Server Core installation of a Windows Server operating system."
So, you mileage may vary.

Related

PowerShell, force Internet Explorer to perform its first-launch configuration?

I often hit the dreaded Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again error when using Invoke-WebRequest.
Various pages point out this issue and the use of the UseBasicParsing switch, but it is an annoyance to have to put that into every command.
Is there a way that I can declare, at the start of a script, some commands to force Internet Explorer to silently perform its first-launch configuration and accept all defaults so that the UseBasicParsing switch is no longer required?
This answer on the page you provided actually suggests setting the registry value with PowerShell that will disable the first run wizard for Internet Explorer and allow you to use Invoke-WebRequest without -UseBasicParsing parameter.
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Internet Explorer\Main" -Name "DisableFirstRunCustomize" -Value 2

Remote execution of powershell script with autosys - to interact with IE _ComObject

I have a Powershell script designed to automate the testing of some URLs. The script invokes an Internet Explorer session as such:
$IEProcess = Start-Process -FilePAth 'C:\Program Files (x86)\Internet Explorer\iexplore.exe' -ArgumentList "-private $url"
$Shell = New-Object -ComObject Shell.Application
$IE = $Shell.Windows()
It then proceeds to use the $IE object to navigate to different URLs, perform various checks against the pages HTML document bodies and take screenshots of the resulting web pages. Ultimately, the IE session is ended and the screenshots are distributed via email as attatchments.
The script works perfectly when logged onto the virtual host-machine with a service account, that has the necessary permissions for single-sign-on to the various URLs. However, the requirement is for the script to run remotely as a scheduled task, on a daily basis. There should be no interaction by a user other than opening the resulting email.
I have had a job set up in AutoSys to execute the script remotely, once a day, with highest privileges; but the script fails to complete as expected. Specifically, the .Windows() method fails passing the following error message:
Exception calling "Windows" with "0" argument(s): "The server process could not
be started because the configured identity is incorrect. Check the username an
d password. (Exception from HRESULT: 0x8000401A)"
I have to give the job of scheduling the task in autosys to someone else (for security reasons) but I trust that they have configured the job with the appropriate username/password for the necessary service account.
Some online sources suggest to me that the issue might lie with trying to use _ComObjects remotely, and that instances of Internet Explorer require an interactive user session with a UI - which isn't standard config for an autosys batch job.
I have had my autosys-guy add a flag to the job description which should make the user session "interactive", but the script still doesn't execute correctly.
I'm looking for some general insight on the topic and hopefully a solution to get the job running. If anyone cares to help me out I would greatly appreciate it! :)
I also have a more focussed question:
Even if I managed to get a handle on the IE session, should I expect the screenshots that the script takes to fail since the screen buffer for the VM has no monitor to render to? - The images are bitmap and refer to the IE shell objects "position", "width" and "height" for capture placement/dimensions; which presumably mean nothing without a screen resolution??
Thank you for taking the time to read my issue!

Wait for Active Directory Authentication URL list to update within a Powershell Azure Function

I need to ensure a reply url is added to a v2 Active Directory App before returning a HTTP response within a Powershell Serverless Function.
Currently I've successfully managed connecting to azure using a service principal, getting the active directory application & updating the authentication list with a new reply url.
This works great but there seems to be some propagation period on completing the job. Everything happens as mentioned in a Powershell Serverless Function & returns a 200 HTTP status when finished.
Once the response (HTTP 200 OK) is received I'm using the Active Directory Authentication Library (ADAL) to log in from some JS app using a full page redirect.
This is where the issue lies, once the Powershell runs & returns the client app tries to login with ADAL but that Active Directory prompts with an error, the supplied url isn't one currently on the authentication list.
I've looked into Start-ThreadJob & Wait-Job but not sure if number one I'm using it correctly or number two it is the best approach.
Example code:
$appId = <ACTIVE_DIRECTORY_APP_ID>
$url = <NEW REPLY URL>
$password = ConvertTo-SecureString -String $env:SERVICE_PRINCIPAL_SECRET -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($env:SERVICE_PRINCIPAL_ID, $password)
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $env:TENANT_ID
$app = Get-AzADApplication -ApplicationId $appId
$replyUrlList = $app.ReplyUrls
$replyUrlList.Add($url)
Update-AzADApplication -ApplicationId $appId -ReplyUrl $replyUrlList
$status = [HttpStatusCode]::Created
$body = "URL Added Successfully"
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = $status
Body = $body
})
At the moment the AD authentication list is updated anywhere from 1 minute - 5 minutes in some cases. Depending if the function is booting from cold-start.
Should I use a loop to check the AD Application information within the Powershell script?
Should I use job threading & wait job cmdlets?
Maybe throw in a bit of sleep?
Just looking for the best approach here to guarantee the new callback url is 100% added before trying to authenticate with the ADAL library.
Any help would be great!
This is not an answer with a solution. But I think I'm reading something that I have experienced on several occasions.
I've been using python and Hashicorp vault to try and manage tokens/RBAC on applications. But very often it would break because it had not updated yet, due to the propagation from AAD to back end being asynchronous from what I was told.
I even did checks where I used ADAL to loop over the application to verify if it was good. But even then it would still fail on some occasions. Which hurt the automation I was trying to put in place.
Now you are having some issue that seems similar, but instead while adding the reply url to an existing application.
My question for testing is; does the reply URL work when it is supplied upon creation of the application? If so, and testing is 100%, then you are having the same issue.
For me, pre-creation of all necessary properties on applications is what helped me circumvent this annoying issue. As I don't think adding a sleep anywhere is a good way to move forward, and the reply from the API isn't reliable enough to work on.
If pre-creation is not an option, I suppose the sleep timer is probably some way forward. For me, that ended up being 2-5m in some cases. And in some lucky cases 7-30s

How do I run Invoke-WebRequest cmdlet from third party program?

I have been trying to get this to work via a game control panel TCAdmin.
$ModPg1 = Invoke-WebRequest "http://steamcommunity.com/sharedfiles/filedetails/?id=731604991"
$ModVer1 = ($ModPg1.ParsedHtml.getElementsByTagName('div') | Where{ $_.className -eq 'detailsStatRight' } ).innerText | Select -Last 1
If I run this cmdlet via a program like TCAdmin (or task scheduler), I get the following error....
Invoke-WebRequest : The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.
Explorer is installed, and set up. The script works just fine if I run it manually.
My guess is there is a way to get TCAdmin to run the scripts the same way I would as a windows User.
Cant find a way nearly as simple to scrape the info 'm looking for.
As for this...
get TCAdmin to run the scripts the same way I would as a windows User.
For any app to run as a user, that users profile must be used on the host where the code is to be run. You cannot natively run PoSH on a host as another user context. This is not a PoSH issue, it is a Windows User Principal security boundary. There are tools that let you do this. For example SysInternal PSExec and AutoIT. Yet as stated that error is pretty specific. The user profile for Internet Explorer has not been created and that only happens when you use IE at least once.
So, as Adam points, out, use the setting the error message states to use or use your code to start IE at least once.
$SomeUrl = 'https://stackoverflow.com'
$ie = New-Object -com internetexplorer.application
$ie.visible = $true
$ie.navigate($SomeUrl)
while ($ie.Busy -eq $true) { Start-Sleep -Seconds 1 } # Wait for IE to settle.
Again, if trying to run this in the context of another user, the two above tools will get you there, but you still have to fire up IE to have a profile for it.

Popup message for current user after script powershell

I created PowerShell script wich install an application on computer (windows 7).
This script is in GPO and deployed with GPO at logon users. This worked fine, but I want that at the end of installation, my powershell script send at the current logged user on computer a message like "Reboot your computer please".
I tested many things but I don'tview popup, maybe because my script are execute with admin rights (not with user rights).
Test :
#$wshell = New-Object -ComObject Wscript.Shell
#$wshell.Popup("Operation Completed",0,"Done",0x1)
[Windows.Forms.MessageBox]::Show(“My message”, , [Windows.Forms.MessageBoxButtons]::OK, [Windows.Forms.MessageBoxIcon]::Information)
Your script may be popping up the message but then closing the PowerShell console immediately after, removing the popup. Try waiting on the result of the popup before closing the PowerShell instance:
$wshell = New-Object -ComObject Wscript.Shell
$result = $wshell.Popup("Operation Completed",0,"Done",0x1)
You need to load the assembly providing the MessageBox class first, and you cannot omit the message box title if you want to specify buttons and/or icons.
Add-Type -Assembly 'System.Windows.Forms'
[Windows.Forms.MessageBox]::Show(“My message”, "", [Windows.Forms.MessageBoxButtons]::OK, [Windows.Forms.MessageBoxIcon]::Information)
# ^^
You can use an empty string or $null here, but simply not providing a value (like you could do in VBScript) is not allowed.
As a side-note, I'd recommend avoiding typographic quotes in your code. Although PowerShell will tolerate them most of the time, they might cause issues sometimes. Always use straight quotes to be on the safe side.
Edit: Since you're running the script via a machine policy it cannot display message boxes to the logged-in user, because it's running in a different user context. All you can do is have a user logon script check whether the software is installed, and then display a message to the user. This works, because a user logon script running in the user's context.