powershell could not create ssl/tsl secure - powershell

I'm using a powershell script to download and execute a file, but since some time I go I get a could not create ssl/tsl secure channel.
$down = New-Object System.Net.WebClient;
$url = 'url';
$file = 'file';
$down.DownloadFile($url,$file);
$exec = New-Object -com shell.application;
$exec.shellexecute($file);
exit;

TLS 1.2 should be enabled to get it working. In PowerShell you can find out which protocols your system supports by running this code:
[Enum]::GetNames([Net.SecurityProtocolType]) -contains 'Tls12'
If the result is True then your system supports TLS 1.2. You can find out which protocols are being used by running:
[System.Net.ServicePointManager]::SecurityProtocol.HasFlag([Net.SecurityProtocolType]::Tls12)
If the result is True then TLS 1.2 is being used . However, you can add TLS 1.2 explicitly by using:
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
This should solve these problems.

It may be that the site you are connection to requires TLS 1.2, whereas powershell uses TLS 1.0 by default (if I remember correctly)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$down = New-Object System.Net.WebClient
$url = 'https://github.com/mpdairy/posh.git'
$file = 'C:\ExistingDirectory\test.git'
$down.DownloadFile($url,$file)
$exec = New-Object -com shell.application
$exec.shellexecute($file)
exit
Without using Tls 1.2, I get this error:
Exception calling "DownloadFile" with "2" argument(s): "The request was aborted: Could not create SSL/TLS
secure channel."
At line:1 char:1
+ $down.DownloadFile($url,$file)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException

I ran into the same error trying to install Wiki.js in Windows server. The issue was the ps1 script included TLS 1.1 as a fallback. The steps below can be changed for any other powershell install
To fix this;
I downloaded the install.ps1 file from installation instructions on Wiki.js installation
iex ((New-Object System.Net.WebClient).DownloadString('https://wiki.js.org/install.ps1'))
Removed "tls11, tls" from the first line
From:
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
To:
[Net.ServicePointManager]::SecurityProtocol = "tls12"
Saved the file in a local directory and changed directory (CD) into
the local directory Ran the command
"iex .\install.ps1"
It's all good now.

Refer this sample code. I written this couple of years when Terraform moved to TLS.
$source=<folder where file suppose to be present>
Write-Verbose -Verbose "Downloading Terraform Required"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::TLS12
$wc = New-Object System.Net.WebClient
if ((test-path "${source}\terraform.zip") -eq $false) {
$wc.downloadfile("https://releases.hashicorp.com/terraform/0.11.2/terraform_0.11.2_windows_amd64.zip","${source}\terraform.zip")
}
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipFile]::ExtractToDirectory("$source\terraform.zip", $destination)

I had the same problem just before and how I fixed it is by changing the link. Make sure the page you're trying to download is a RAW file, for example -
https://raw.githubusercontent.com/TTT2866/Batch-username-generator/master/username_generator.bat
and not
https://github.com/TTT2866/Batch-username-generator/blob/master/username_generator.bat
Note the "raw" in the first link

Related

downloading a web page with powershell using a x.509 certificate

I am having a problem with PowerShell on Windows 10 trying to download a file from a site that uses an X.509 certificate to authenticate the client. I have this certificate installed in my certificate store in IE and I also have exported the PFX file. Here's what I have tried:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::ssl3 and also tls12
trying to get the certificate using System.Security.Cryptography.X509Certificates.X509Certificates2
trying to set the credentials via Get-Credential and then passing it
I've used the Invoke-WebRequest command as well as System.Net.WebClient trying to get this to work. The error message I'm getting is as follows:
PS P:\PSScripts> P:\PSScripts\DownloadSslHtml.ps1
VERBOSE: GET https://somewebsite.com/GetReports.do?reportTypeId=1234
with 0-byte payload
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.
At P:\PSScripts\DownloadSslHtml.ps1:20 char:1
+ Invoke-WebRequest -Uri $url -UserAgent ([Microsoft.PowerShell.Command ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-
WebRequest], WebException + FullyQualifiedErrorId :
WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Now I have seen a lot of people with this "SSL/TLS secure channel" error and they fixed it by specifying the encryption method as TLS12 or SSL3, neither of which is working for me. I'm confused how to proceed. Any thoughts? The website is using TLS1.2 AES with 256 bit encryption ECDH 256 bit exchange.
EDIT: Here's my powershell code:
$url = "https://somewebsite.com/GetReports.do?reportTypeId=1234"
$outputFile = "P:/DownloadedData/file.html"
$PFXPath = "P:/Properties/Config/mycert.pfx"
$PFXPassword = "cert_password"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::tls12
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($PFXPath,$PFXPassword,'DefaultKeySet')
Invoke-WebRequest -Uri $url -UserAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer) -Certificate $cert -OutFile $outputFile -Verbose
I changed this line:
$cert.Import($PFXPath,$PFXPassword,'DefaultKeySet')
to this:
$cert.Import($PFXPath,$PFXPassword,'UserKeySet')
And now it works!

Use Connect-SPOService with Powershell 6 (core version)

I'm trying to connect to a sharepoint environment and I want to do that with Powershell version 6. Why? Eventually, I want to put the PS commands in a .net core 3 application. And as far as I know I cannot use PS5.1 in .net core.
It is about this powershell script:
Import-Module -Force -name Microsoft.Online.SharePoint.PowerShell;
Import-Module -Force -name Microsoft.Online.SharePoint.PowerShell -DisableNameChecking;
$username = 'admin#shootme.com';
$password = 'right now';
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $Password -asplaintext -force);
Connect-SPOService -Url https://shootme.sharepoint.com -Credential $cred;
When I try this in the default PS 5.1 it just works fine. When I try this with PS 6.2.3, I get an error:
Connect-SPOService : The remote server returned an error: (400) Bad Request.
At line:1 char:1
+ Connect-SPOService -Url https://shootme.sharepoint.com -Credent ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Connect-SPOService], WebException
+ FullyQualifiedErrorId : System.Net.WebException,Microsoft.Online.SharePoint.PowerShell.ConnectSPOService
Does the newer Powershell have different syntax orso, of what am I doing wrong?
Also, maybe there is a way to run scripts in ps 5.1 when running them in .net core?
Have you tried connecting manually by removing the credentials portion and letting it prompt you for a login and test if that resolves successfully?
Edit: I do know you can also call powershell from a .bat like so:
powershell -version 2 .\xyz.ps1
But not knowing what you're going for exactly makes it tough to suggest if that's even a viable option.

powershell Accepting self-signed certificates using ServerCertificateValidationCallback

I cannot seem to get this to work using Powershell 5.1. The device is a Cisco MX800 CE9.3.
$url = "https://10.1.135.20/getxml?location=/Status"
[Net.ServicePointManager]::ServerCertificateValidationCallback={$true}
$webclient = New-Object System.Net.Webclient
$credCache = New-Object System.Net.CredentialCache
$creds = New-Object System.Net.NetworkCredential($user,$pwd)
$credCache.Add($url, "Basic", $creds)
$webclient.Credentials = $credCache
$webpage = $webclient.DownloadString($url)
Running this script using http returns XML as expected, but using https returns the error below
Exception calling "DownloadString" with "1" argument(s): "The underlying connection was closed: An unexpected error occurred on a send."
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException
In the case above, after searching for answers, I dug in and did packet captures.
One packet capture with powershell talking to the server and one packet capture with a web browser talking to the server.
The PS Client Hello was using TLS1.0
The Web browsers Client Hello was using TLS1.2
So, in PS I added this to the code and I was able to use https against the server.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Access denied while running Windows Update using Powershell's Invoke-Command

I've been trying to setup a Powershell module that would remotely call Windows/Microsoft update on a server using Invoke-Command, then process the updates, and send everything back to the calling server so it can send an email report.
My issue comes when I try and call the downloader: Powershell seems to be requesting Elevated rights on the remote computer.
Here is a snippet of what I'm trying to run and fail:
Invoke-Command -ComputerName $Server -Credential $Credentials -ScriptBlock {
$UpdateSession = New-Object -ComObject "Microsoft.Update.Session"
Write-Progress -Activity "Updating" -Status "Checking for new updates"
$Criteria = "IsInstalled=0 and Type='Software'"
$Updates = $UpdateSession.CreateUpdateSearcher().Search($Criteria).updates
$Downloader = $UpdateSession.CreateUpdateDownloader()
$Downloader.Updates = $Updates
}
I know the issue isn't with remoting, as the first 4 commands work fine.
The $Credentials variable points to pre-defined credentials, which are Local Admin on the remote server.
When the script gets to the 5th line, $Downloader = $UpdateSession.CreateUpdateDownloader(), I get this error from Powershell:
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
+ CategoryInfo : OperationStopped: (:) [], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException
+ PSComputerName : SERVER.sidlee.inc
What could be causing this exactly ?
Thanks in advance for the help!
As i just hit the same wall, and Google isn't of much help either, here is what i could dig up.
For the record, i am pretty much doing the same thing (using custom PS code to check remote systems for Windows Updates) but using WinRM over Python instead of Invoke-Command and also got stuck on Microsoft.Update.Searcher.Search() throwing a E_ACCESSDENIED error.
The UnauthorizedAccessException is indeed not related to Powershell but the underlying API.
I suspect Microsoft started cutting off impersonation in remote session in some recent update (Powershell v5?) as this was (and still is) working just fine on older Windows versions (e.g. Server 2012 with Powershell v3 or 2012 R2 with v4)
To get around this you will need to authenticate (on the remote server) prior to executing your stuff with a PSCredential object.
So Remote Auth -> Local Auth -> Run stuff for example using Start-Process -Credential ...
e.g.
$pass = ConvertTo-SecureString "PA$$W0RD" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential "User", $pass
Start-Process -Credential $creds powershell -ArgumentList "-Command & { ... whatever you want to do ... }"
Keep in mind that this poses a security risk as your password will be parsed in clear text, so don't do this over an
unencrypted channel!

Error uploading file to FTP Server

I'm trying to use FTP to upload a file to an FTP server. I found the following script online, but I can't get it to work.
$UserName = 'username'
$Password = 'password'
$LocalFilePath = 'c:\FolderName\x.txt'
$RemoteFileName = 'x.txt'
$ServerName = 'my.ftpserver.co.uk'
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($UserName, $Password)
#Connect to FTP
$uri = New-Object System.Uri(“ftp://$ServerName/$RemoteFileName”)
write-host $uri
#upload as file
$webclient.UploadFile($uri, $LocalFilePath)
But when I run this I get the following error:
Exception calling "UploadFile" with "2" argument(s): "An exception occurred during a WebClient request."
At line:21 char:22
+ $webclient.UploadFile <<<< ($uri, $LocalFilePath)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Can anyone point me in the right direction?
I can connect using Filezilla etc from my PC, so it's not blocked by the firewall or anything,
Tested your script and it runs fine, only way I'm able to reproduce your error is if I point $LocalFilePath to a file that doesn't exist. Could you try:
Test-Path($LocalFilePath)
And see if it returns True?
From your comment and the code I see in the question the issue could just be the fact that you have smart quotes in there. It would be a product of your coding editor or the source of copying and paste that code into your environment. You need to watch out for these things. Assuming the paths are correctly formed perhaps that is just your issue.
Smart Quotes
$uri = New-Object System.Uri(“ftp://$ServerName/$RemoteFileName”)
Proper double quotes
$uri = New-Object System.Uri("ftp://$ServerName/$RemoteFileName")
The quotes in the second example are the ones you should use.