Powershell 4 too old for tls 1.2? - powershell

I have a Windows Server 2012R2 with powershell 4.
A sql job issues a
Invoke-WebRequest https://someserver/file.xml -OutFile c:/tmp/data.xml"
It fails with ssl error, even if I follow
Powershell Invoke-WebRequest Fails with SSL/TLS Secure Channel and prepend [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" or the other variations.
Is powershell 4 too old?
Should I try installing Wowershell 6 or 7 from https://github.com/PowerShell/PowerShell/releases ?
Will that be invoked by the sqljob, or should it be specified somewhere/somehow that it's supposed to run v7 instead of v4?
PS: I know "Windows Server 2012 R2 entered mainstream support on November 25, 2013, though, but its end of mainstream is January 9, 2018, and end of extended is January 10, 2023" but upgrading is not an option right now.
EDIT
I installed powershell 5.1, it didn't change
Major Minor Build Revision
----- ----- ----- --------
5 1 14409 1005
and do
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
But still get
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.
EDIT 2
PS C:\Users\leif> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

I believe it is. Powershell relies upon the .Net framework under the hood. PS version 4 uses .Net 4.0 which I believe did not have support for TLS 1.2 added or enabled by default.
See:
https://learn.microsoft.com/en-us/powershell/scripting/install/windows-powershell-system-requirements?view=powershell-7
TLS 1.2 was made the default protocol in .Net 4.6
See:
https://blogs.perficient.com/2016/04/28/tsl-1-2-and-net-support/
Make note of:
NET 4.0. TLS 1.2 is not supported
So you're going to need to code around it as others have suggested or upgraded to WMF 5.1. Before completing the upgrade be sure to make sure it will not break anything. Some MS products, like SharePoint, may not be compatible with the newer version.
Also, try setting your TLS via:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
The above assumes a PowerShell version with support.

Related

Powershell: PSSQLITE module suddenly didn't work

I'm on Win10+PS 7.1.
I used the PSSQLITE module v1.1.0 for one or two months, it worked perfectly. I used it even yesterday.
But today it suddenly didn't work.
$db = Get-DefaultSourceDB
$sql = "select * from users"
$result = Invoke-SqliteQuery -DataSource $db -Query $sql
Line |
429 | … $conn = New-Object System.Data.SQLite.SQLiteConnection -ArgumentL …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Exception calling ".ctor" with "1" argument(s): "Unable to load DLL 'SQLite.Interop.dll' or one of its
| dependencies: The specified module could not be found. (0x8007007E)"
I didn't touch anything on my PC. I uninstalled then reinstalled the pssqlite module but it didn't help.
I can see the SQLite.Interop.dll is a self-contained dll file in the PSSQLITE module. I see there's code in the module to check the OS version and load the necessary ones.
I have no clue and I've struggled on it for the whole day.
Can you please help?
BTW - this works under PS 5.1 on the same machine(same PSSQLITE version, seperate installation directory) but I have some other stuff didn't work under PS5.1
Here's my environment:
Name Value
---- -----
PSVersion 7.1.0
PSEdition Core
GitCommitId 7.1.0
OS Microsoft Windows 10.0.18363
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0

The term 'Invoke-WebRequest' is not recognized as the name of a cmdlet

I've got problem with executing Invoke-WebRequest cmdlet. I read that ~100% case of that scenario is PS version lower than 3, but it's not my case:
Name Value
---- -----
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
CLRVersion 4.0.30319.34011
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.10208.0
PSVersion 5.0.10208.0
SerializationVersion 1.1.0.1
I can add that I'm using Windows 10 IoT Core version of OS. In fact my main purpose is execution of simple web request, but I am interested why this cmdlet is not working, especially if more of them won't be ;/ I suppose it can be some windows feature like switch to turn on, but its just my guess.
Update
As far as I compared available cmdlets for certain modules, and preloaded assemblies between my regular system and an IoT version, it looks like the latter version is cut somehow, but I still didn't see any docs for that.
I had this issue on a Windows Server 2008 R2 server, because it was running PowerShell v2. Upgrading to v4 fixed the issue.
Windows Management Framework 4.0 (includes PowerShell 4.0)
As of v5, Invoke-WebRequest is still documented.
Check your version with:
$PSVersionTable.PSVersion
Trying to create the request in the same way I would do it for PS version 2 (using .net library instead of cmdlet) doesn't work either...
$request = [System.Net.WebRequest]::Create("https://google.com")
$request.Method = "GET"
[System.Net.WebResponse]$response = $request.GetResponse()
This appears to be removed in PowerShell Core.
I am searching for why this doesn't work on Docker for Windows running on Nano Server for Windows 2016 and your findings match mine.
Though the PowerShell version and everything else was good at my end, I was unable to download the code from the desired repo. So, I've executed the following command first to satisfy the TLS version, and then I have executed my desired command to download the latest version of the githubActions runner.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri
https://github.com/actions/runner/releases/download/v2.165.2/actions-runner
-win-x64-2.165.2.zip -OutFile actions-runner-win-x64-2.165.2.zip
Invoke-WebRequest has been stripped from PowerShell 5.
Here's an implementation of a function called Invoke-FastWebRequest that works just like the old Invoke-WebRequest in PowerShell 5: https://github.com/cloudbase/unattended-setup-scripts/blob/master/FastWebRequest.psm1
Using -UseBasicParsing option in the command works. The following is part of the command's documentation
-UseBasicParsing
Indicates that the cmdlet uses the response object for HTML content without Document Object Model (DOM) parsing.
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.

Forcing version 2 on remote session for SharePoint management using Powershell

It seems that SharePoint 2010 is still incompatible with PowerShell version 3.0.
I am already aware that it is possible to force compatibility by executing PowerShell with the -v 2 switch, but is there a way to force this compatibility mode when using a remote session via PSSession as using a remote desktop is quite impractical just to launch a shell?
If you start the client PowerShell with -v 2. Then outgoing remote sessions should use v2 on the remote end automatically.
Update: it appears I am mistaken - I think in fact I had discussed this with the PowerShell team, but apparently it's not fixed. Anyway, you can create a session configuration on the server that is forced to version 2.0:
PS> $psversiontable
Name Value
---- -----
PSVersion 3.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.18010
BuildVersion 6.2.9200.16434
PSCompatibleVersions {1.0, 2.0, 3.0}
PSRemotingProtocolVersion 2.2
PS> Register-PSSessionConfiguration -PSVersion '2.0' -Name "powershell2"
Accept all of the prompts. Now, you must pass the name of the new remote session configuration when invoking from the client side (in this example, the client and server are the same machine: my desktop)
PS> icm localhost -ConfigurationName powershell2 { $psversiontable }
Name Value
---- -----
PSRemotingProtocolVersion 2.1
BuildVersion 6.1.7600.16385
PSCompatibleVersions {1.0, 2.0}
PSVersion 2.0
CLRVersion 2.0.50727.6400
WSManStackVersion 2.0
SerializationVersion 1.1.0.1
As you can see, the remote endpoint is running 2.0.
I hope this helps.

Powershell v3.0 pipe issue

I'm having trouble with this command:
gc .\domains.txt | Get-ADDomain
As the name implies, domains.txt contains a list of Active Directory to query (all domains are in the same forest).
If I run it on my Windows 8 machine everything works fine and I get the expected results, instead on a Windows 2008 R2 SP1 member server (not a DC) with WMF 3.0 I get result only from the first domain in the list and for the others:
Get-ADDomain : A referral was returned from the server
If I query a domain in the list with:
Get-ADDomain <Domain name here>
it works fine.
My Workstation
Microsoft Windows 8 Enterprise (6.2.9200) x64
PS D:\Tools\Powershell> $PSVersionTable
Name Value
---- -----
PSVersion 3.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.18010
BuildVersion 6.2.9200.16384
PSCompatibleVersions {1.0, 2.0, 3.0}
PSRemotingProtocolVersion 2.2
Server
Microsoft Windows Server 2008 R2 Standard SP1 (6.1.7601) x64
PS C:\Tools\Powershell> $PSVersionTable
Name Value
---- -----
WSManStackVersion 3.0
PSCompatibleVersions {1.0, 2.0, 3.0}
SerializationVersion 1.1.0.1
BuildVersion 6.2.9200.16398
PSVersion 3.0
CLRVersion 4.0.30319.269
PSRemotingProtocolVersion 2.2
Update
If i run on the server:
gc .\domains.txt | %{ Get-ADDomain $_ }
it runs fine
TRACE
trace-command -Name ParameterBinding { "DOMAIN_1","DOMAIN_2" | Get-ADDomain } -PSHost
Server: http://pastebin.com/sRVJHaCU
Workstation: http://pastebin.com/kj3JV6nV
Thanks in advance
I found an article that may help.
http://technet.microsoft.com/en-us/library/ee617224.aspx
From the look of your script you are providing the server using the text file. Is it possible the problem is the Windows 2008 server you are running the PowerShell script on is not in the same domain or the user you are logged in as does not have access to the domains where the other servers are members?
snippet from the above article:
-If the Server parameter is specified and the Credential parameter is not specified:
--The domain is set to the domain of the specified server and the cmdlet checks to make sure that the server is in the domain of the
LocalComputer or LoggedOnUser. Then the credentials of the current
logged on user are used to get the domain. An error is returned when
the server is not in the domain of the LocalComputer or LoggedOnUser.
You might try adding the additional parameters for the Get-ADDomain commandlet such as -Identity, -AuthType, and -Credential
Get-ADDomain [-Identity] [-AuthType { |
}] [-Credential ] [-Server ]
[]
Powershell v3.0 pipe issue
I just tried to run the cmdlet 'gc .\text.txt | Get-ADDomain' from a virtual Server 2008 R2 box that I have. I built a text file in the following format:
Domain1
Domain2
Domain3
One thing to be sure of is that each domain is on it's own line in the text file. I can understand why the one syntax worked when you piped the STDOUT to:
%{ Get-ADDomain $_}
because you are looping through all the information contained in the text file and only have the cmdlet work on a single value at a time. Unfortunately I don't have the RSAT package on my Win 8 desktop, so I can't test from my desktop. Hopefully this helps a little bit.

PowerShell's Invoke-Expression missing param

I thought that I had the latest CTP of PowerShell 2 but when I try the command:
invoke-expression –computername Server01 –command 'get-process PowerShell'
I get an error message:
A parameter cannot be found that matches parameter name 'computername'.
So the question is: How can I tell which version of PowerShell I have installed? And what the latest version is?
From last night's build (which means you might have this in CTP3 but if not, you'll get it in the next public drop):
[4120:0]PS> $psversiontable
Name Value
---- -----
CLRVersion 2.0.50727.3521
BuildVersion 6.1.7047.0
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.0
Experiment! Enjoy! Engage!
Jeffrey Snover [MSFT]
Windows Management Partner Architect
The problem is that from CTP 1 to CTP2, they switched up the Invoke stuff, all the remoting stuff is done through Invoke-Command now, and Invoke-Expression is solely for turning a string into a script ;)
P.S.: If you're on v2 you can run $PSVersionTable to see a list of versions including the CLR and Build versions.
$host.version.tostring() will return the version number.
RTM of v1 is 1.0.0.0
Couldn't honestly tell you what the latest version of the previews are because I haven't had a chance to play yet.
The latest CTP is CTP2 released on 05/02/08 and can be found here. Remoting requires WinRM to be installed on both the calling machine and the target machine. Included in the CTP is a script to configure WS-Management called Configure-WSMan.ps1.
This command should get you the version number of PowerShell that you have installed.
Get-Command "$PSHome\powershell.exe" | Format-List FileVersionInfo
V1.0 is 6.0.5430.0
CTP2 is 6.1.6585.1
I don't have the version number for the first CTP on hand, but I can find it if you really need it.
I'm guessing that this is a change to the cmdlet made during the configuration process Configure-Wsman.ps1. I don't have an environment setup to test right now, but I'm guessing something went wrong with the configuration. I can verify that on XP the parameter is not available (duh). I'd assume that you will find the same on Vista/08 without the configuration completed.
If the $PSVersionTable variable doesn't exist, then you are running V1.
If it exists, then the version will be available as $PSVersionTable.PSVersion.
function Get-PSVersion {
if (test-path variable:psversiontable)
{$psversiontable.psversion}
else
{[version]"1.0.0.0"}
}