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.
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.
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.
We are providing scripts to clients that will be working only in Powershell 2.0.
Through command we can ensure that powershell 2.0 is installed like below
$version = Get-host | Select-object Version
But if we provide script how to ensure that they are executing it from Powershell 2.0?
When executing the script , Powershell 2.0 features may give script errors while initiating the script itself.Isn't it?
You can annotate your script with #requires and state that it shouldn't run on anything less than PowerShell v2:
#requires -Version 2.0
(Side note: This is surprisingly hard to find even if you know vaguely that it exists.)
Relying on the host version is not the safest thing to do as the script can be run on hosts that do not have the same host version as PowerShell's version.
The $PSVersionTable variable was added in v2. You can check if the variable exists, if it does you're running v2 and above, you can also check PSVersion.Major property:
if($PSVersionTable)
{
'PowerShell {0}' -f $PSVersionTable.PSVersion.Major
}
else
{
'PowerShell 1'
}
I'd do something like this:
# get version
$ver = $PsVersionTable.psversion.major
# Check to see if it's V2
If ($ver -NE 2)
{"incorrect version - exiting; return}
# Everything that follows is V2
Hope this helps!
Try to use $PSVersionTable
You will get something like:
Name Value
---- -----
CLRVersion 2.0.50727.5456
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
How can I determine what version of PowerShell is installed on a computer, and indeed if it is installed at all?
Use $PSVersionTable.PSVersion to determine the engine version. If the variable does not exist, it is safe to assume the engine is version 1.0.
Note that $Host.Version and (Get-Host).Version are not reliable - they reflect
the version of the host only, not the engine. PowerGUI,
PowerShellPLUS, etc. are all hosting applications, and
they will set the host's version to reflect their product
version — which is entirely correct, but not what you're looking for.
PS C:\> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
4 0 -1 -1
I would use either Get-Host or $PSVersionTable. As Andy Schneider points out, $PSVersionTable doesn't work in version 1; it was introduced in version 2.
get-host
Name : ConsoleHost
Version : 2.0
InstanceId : d730016e-2875-4b57-9cd6-d32c8b71e18a
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-GB
CurrentUICulture : en-US
PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
$PSVersionTable
Name Value
---- -----
CLRVersion 2.0.50727.4200
BuildVersion 6.0.6002.18111
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
You can look at the built in variable, $psversiontable. If it doesn't exist, you have V1. If it does exist, it will give you all the info you need.
1 > $psversiontable
Name Value
---- -----
CLRVersion 2.0.50727.4927
BuildVersion 6.1.7600.16385
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
To determine if PowerShell is installed, you can check the registry for the existence of
HKEY_LOCAL_MACHINE\Software\Microsoft\PowerShell\1\Install
and
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3
and, if it exists, whether the value is 1 (for installed), as detailed in the blog post Check if PowerShell installed and version.
To determine the version of PowerShell that is installed, you can check the registry keys
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine\PowerShellVersion
and
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\PowerShellVersion
To determine the version of PowerShell that is installed from a .ps1 script, you can use the following one-liner, as detailed on PowerShell.com in Which PowerShell Version Am I Running.
$isV2 = test-path variable:\psversiontable
The same site also gives a function to return the version:
function Get-PSVersion {
if (test-path variable:psversiontable) {$psversiontable.psversion} else {[version]"1.0.0.0"}
}
You can directly check the version with one line only by invoking PowerShell externally, such as from Command Prompt
powershell -Command "$PSVersionTable.PSVersion"
According to #psaul you can actually have one command that is agnostic from where it came (CMD, PowerShell or Pwsh). Thank you for that.
powershell -command "(Get-Variable PSVersionTable -ValueOnly).PSVersion"
I've tested and it worked flawlessly on both CMD and PowerShell.
You can verify that Windows PowerShell version installed by completing the following check:
Click Start, click All Programs, click Accessories, click Windows PowerShell, and then click Windows PowerShell.
In the Windows PowerShell console, type the following command at the command prompt and then press ENTER:
Get-Host | Select-Object Version
You will see output that looks like this:
Version
-------
3.0
http://www.myerrorsandmysolutions.com/how-to-verify-the-windows-powershell-version-installed/
Microsoft's recommended forward compatible method for checking if PowerShell is installed and determining the installed version is to look at two specific registry keys. I've reproduced the details here in case the link breaks.
According to the linked page:
Depending on any other registry key(s), or version of PowerShell.exe or the location of PowerShell.exe is not guaranteed to work in the long term.
To check if any version of PowerShell is installed, check for the following value in the registry:
Key Location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1
Value Name: Install
Value Type: REG_DWORD
Value Data: 0x00000001 (1
To check whether version 1.0 or 2.0 of PowerShell is installed, check for the following value in the registry:
Key Location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine
Value Name: PowerShellVersion
Value Type: REG_SZ
Value Data: <1.0 | 2.0>
I found the easiest way to check if installed was to:
run a command prompt (Start, Run, cmd, then OK)
type powershell then hit return. You should then get the PowerShell PS prompt:
C:\Users\MyUser>powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.
PS C:\Users\MyUser>
You can then check the version from the PowerShell prompt by typing $PSVersionTable.PSVersion:
PS C:\Users\MyUser> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
2 0 -1 -1
PS C:\Users\MyUser>
Type exit if you want to go back to the command prompt (exit again if you want to also close the command prompt).
To run scripts, see http://ss64.com/ps/syntax-run.html.
$host.version is just plain wrong/unreliable. This gives you the version of the hosting executable (powershell.exe, powergui.exe, powershell_ise.exe, powershellplus.exe etc) and not the version of the engine itself.
The engine version is contained in $psversiontable.psversion. For PowerShell 1.0, this variable does not exist, so obviously if this variable is not available it is entirely safe to assume the engine is 1.0, obviously.
The easiest way to forget this page and never return to it is to learn the Get-Variable:
Get-Variable | where {$_.Name -Like '*version*'} | %{$_[0].Value}
There is no need to remember every variable. Just Get-Variable is enough (and "There should be something about version").
Use:
$psVersion = $PSVersionTable.PSVersion
If ($psVersion)
{
#PowerShell Version Mapping
$psVersionMappings = #()
$psVersionMappings += New-Object PSObject -Property #{Name='5.1.14393.0';FriendlyName='Windows PowerShell 5.1 Preview';ApplicableOS='Windows 10 Anniversary Update'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.1.14300.1000';FriendlyName='Windows PowerShell 5.1 Preview';ApplicableOS='Windows Server 2016 Technical Preview 5'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.0.10586.494';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3172985 1607'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.0.10586.122';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3140743 1603'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.0.10586.117';FriendlyName='Windows PowerShell 5 RTM 1602';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.0.10586.63';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3135173 1602'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.0.10586.51';FriendlyName='Windows PowerShell 5 RTM 1512';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.0.10514.6';FriendlyName='Windows PowerShell 5 Production Preview 1508';ApplicableOS='Windows Server 2012 R2'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.0.10018.0';FriendlyName='Windows PowerShell 5 Preview 1502';ApplicableOS='Windows Server 2012 R2'}
$psVersionMappings += New-Object PSObject -Property #{Name='5.0.9883.0';FriendlyName='Windows PowerShell 5 Preview November 2014';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows 8.1'}
$psVersionMappings += New-Object PSObject -Property #{Name='4.0';FriendlyName='Windows PowerShell 4 RTM';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
$psVersionMappings += New-Object PSObject -Property #{Name='3.0';FriendlyName='Windows PowerShell 3 RTM';ApplicableOS='Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8, and Windows 7 SP1'}
$psVersionMappings += New-Object PSObject -Property #{Name='2.0';FriendlyName='Windows PowerShell 2 RTM';ApplicableOS='Windows Server 2008 R2 SP1 and Windows 7'}
foreach ($psVersionMapping in $psVersionMappings)
{
If ($psVersion -ge $psVersionMapping.Name) {
#{CurrentVersion=$psVersion;FriendlyName=$psVersionMapping.FriendlyName;ApplicableOS=$psVersionMapping.ApplicableOS}
Break
}
}
}
Else{
#{CurrentVersion='1.0';FriendlyName='Windows PowerShell 1 RTM';ApplicableOS='Windows Server 2008, Windows Server 2003, Windows Vista, Windows XP'}
}
You can download the detailed script from How to determine installed PowerShell version.
PowerShell 7
The accepted answer is only appropriate if one version of PowerShell is installed on a computer. With the advent of PowerShell 7, this scenario becomes increasingly unlikely.
Microsoft's documentation states that additional registry keys are created when PowerShell 7 is installed:
Beginning in PowerShell 7.1, the [installer] package creates registry keys
that store the installation location and version of PowerShell. These
values are located in
HKLM\Software\Microsoft\PowerShellCore\InstalledVersions\<GUID>. The
value of <GUID> is unique for each build type (release or preview),
major version, and architecture.
Exploring the registry in the aforementioned location reveals the following registry value: SemanticVersion. This value contains the information we seek.
On my computer it appears like the following:
Path Name Type Data
---- ---- ---- ----
HKLM:\SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\31ab5147-9a97-4452-8443-d9709f0516e1 SemanticVersion String 7.1.3
As you can see, the version of PowerShell 7 installed on my computer is 7.1.3. If PowerShell 7 is not installed on the target computer, the key in its entirety should not exist.
As mentioned in the Microsoft documentation, the registry path will be slightly different dependent on installed PowerShell version.
Part of the key path changing could pose a challenge in some scenarios, but for those interested in a command line-based solution, PowerShell itself can handle this problem easily.
The PowerShell cmdlet used to query the data in this registry value is the Get-ItemPropertyValue cmdlet. Observe its use and output as follows (note the asterisk wildcard character used in place of the part of the key path that is likely to change):
PS> Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\*" -Name "SemanticVersion"
7.1.3
Just a simple one-liner.
To check if PowerShell is installed use:
HKLM\Software\Microsoft\PowerShell\1 Install ( = 1 )
To check if RC2 or RTM is installed use:
HKLM\Software\Microsoft\PowerShell\1 PID (=89393-100-0001260-00301) -- For RC2
HKLM\Software\Microsoft\PowerShell\1 PID (=89393-100-0001260-04309) -- For RTM
Source: this website.
Since the most helpful answer didn't address the if exists portion, I thought I'd give one take on it via a quick-and-dirty solution. It relies on PowerShell being in the path environment variable which is likely what you want. (Hat tip to the top answer as I didn't know that.) Paste this into a text file and name it
Test Powershell Version.cmd
or similar.
#echo off
echo Checking powershell version...
del "%temp%\PSVers.txt" 2>nul
powershell -command "[string]$PSVersionTable.PSVersion.Major +'.'+ [string]$PSVersionTable.PSVersion.Minor | Out-File ([string](cat env:\temp) + '\PSVers.txt')" 2>nul
if errorlevel 1 (
echo Powershell is not installed. Please install it from download.Microsoft.com; thanks.
) else (
echo You have installed Powershell version:
type "%temp%\PSVers.txt"
del "%temp%\PSVers.txt" 2>nul
)
timeout 15
I needed to check the version of PowerShell and then run the appropriate code. Some of our servers run v5, and others v4. This means that some functions, like compress, may or may not be available.
This is my solution:
if ($PSVersionTable.PSVersion.Major -eq 5) {
#Execute code available in PowerShell 5, like Compress
Write-Host "You are running PowerShell version 5"
}
else {
#Use a different process
Write-Host "This is version $PSVersionTable.PSVersion.Major"
}
The below cmdlet will return the PowerShell version.
$PSVersionTable.PSVersion.Major
This is the top search result for "Batch file get powershell version", so I'd like to provide a basic example of how to do conditional flow in a batch file depending on the powershell version
Generic example
powershell "exit $PSVersionTable.PSVersion.Major"
if %errorlevel% GEQ 5 (
echo Do some fancy stuff that only powershell v5 or higher supports
) else (
echo Functionality not support by current powershell version.
)
Real world example
powershell "exit $PSVersionTable.PSVersion.Major"
if %errorlevel% GEQ 5 (
rem Unzip archive automatically
powershell Expand-Archive Compressed.zip
) else (
rem Make the user unzip, because lazy
echo Please unzip Compressed.zip prior to continuing...
pause
)
I tried this on version 7.1.0 and it worked:
$PSVersionTable | Select-Object PSVersion
Output
PSVersion
---------
7.1.0
It doesn't work on version 5.1 though, so rather go for this on versions below 7:
$PSVersionTable.PSVersion
Output
Major Minor Build Revision
----- ----- ----- --------
5 1 18362 1171
EDIT
As of PowerShell 7.2.5, you can now do:
pwsh -v
Or
pwsh --version
Output
PowerShell 7.2.5
You can also call the "host" command from the PowerShell commandline. It should give you the value of the $host variable.
Very old question but still relevant, it's just that the nature of the problem is different now in 2023. Finding the version is easy, but first we have to launch the right executable. For that, we're basically back to looking in the registry.
reg query "HKLM\SOFTWARE\Microsoft\PowerShell\1" /v Install >nul 2>&1
if %ERRORLEVEL% EQU 0 (
:: Default to PowerShell 5 if both are installed
set PSEXE=powershell
) else (
set PSEXE=pwsh
)
echo Using %PSEXE%
%PSEXE% -ExecutionPolicy bypass -command "& { ... ; exit $LASTEXITCODE }"
There are other hints you can get by inspecting environment variables, but I think testing the registry for 'Windows' PowerShell is the safest.
Extending the answer with a select operator:
Get-Host | select {$_.Version}
I have made a small batch script that can determine PowerShell version:
#echo off
for /f "tokens=2 delims=:" %%a in ('powershell -Command Get-Host ^| findstr /c:Version') do (echo %%a)
This simply extracts the version of PowerShell using Get-Host and searches the string Version
When the line with the version is found, it uses the for command to extract the version. In this case we are saying that the delimiter is a colon and search next the first colon, resulting in my case 5.1.18362.752.