Why does VS Code PowerShell terminal map a new drive? - powershell

I was making a PowerShell script in Visual Studio Code that used the command Get-PSDrive, and to my surprise, it seemed like while using VS Code, a new drive identical to my C:\ drive called Temp appeared.
I was taken aback by this result as as far as I knew, I only had 2 other drives besides my main C:\ drive connected. I tried to replicate this on other terminals with no success except for PowerShell 7:
Windows Terminal PowerShell 5.1
PowerShell 5.1
PowerShell 5.1 (86x)
PowerShell 7 (86x)
Windows Terminal PowerShell 7
As I saw that it was replicated by PwSh 7, I decided to check the versions of each of the PowerShells with the $host variable and I saw something even more unexpected:
Version : 5.1.19041.1
Windows Terminal PowerShell 5.1
Version : 5.1.19041.1
PowerShell 5.1
Version : 5.1.19041.1
PowerShell 5.1 (86x)
Version : 7.0.2
PowerShell 7 (86x)
Version : 7.0.2
Windows Terminal PowerShell 7
which all seemed normal, but when I checked the VSCode $host, I got the result
Version : 2020.6.0
What is causing the differences in the outputs of
Get-PSDrive | Where-Object {$_.Provider.Name -eq "FileSystem"}
between PwSh 7, PowerShell 5.1, and VS Code PwSh?

That Temp: drive is not "a new drive identical to my C:\ drive"; its Root is $Env:Temp, not C:\.
According to PowerShell Team May 2020 Update, which actually describes PowerShell 7.1, this was added in PowerShell 7.0...
In PowerShell 7.0, we added a temp: PSDrive. This works on all platforms and automatically maps to your user temporary path.
By the way, the command you used to make those screenshots could be simplified to Get-PSDrive -PSProvider FileSystem.

Related

.Bat file unable to run powershell 7

I have set up a very simple .bat file to execute a couple of commands to save me typing them out every time, however the processes need to be run in powershell 7.
If i manually run powershell 7.0.3 and then run the commands everything work, however running the .bat script starting
powershell -Version 7.0.3 -Command {XXXXX};
presents me with a message "Cannot start Windows PowerShell version 7.0.3 because it is not installed."
If i try and run it without the version number then it runs in 5.1.x and this then fails as it requires 6+.
tl;dr
As Lee_Dailey notes, you must use pwsh.exe, not powershell.exe, to start a version of PowerShell [Core] v6+ and you must invoke the desired version's specific executable.
In the simplest case:
pwsh -Command "XXXXX"
Note that I've replaced {XXXXX} with "XXXXX", because you cannot directly execute script blocks ({...}) from outside PowerShell - just supply the commands as a string.
Given that - unlike with Windows PowerShell - you can install multiple PowerShell [Core] versions side by side:
Run pwsh -version (sic; see below) to report the version in your system's path (the instance that comes first among the directories listed in the PATH environment variable, $env:PATH).
If it is not the one you want to target, you'll have to invoke it via its full path:
If you want to rely on the standard installation location, you can use the following on Windows for version 7.0: "C:\Program Files\PowerShell\7\pwsh.exe"
To determine the target version's executable location reliably, open an interactive console for it and run (Get-Process -Id $PID).Path
The -Version parameter of powershell.exe, the Windows PowerShell CLI, does not allow you to start just any PowerShell version, only an older version of Windows PowerShell:
In fact, the only supported argument is -Version 2, and even that will only succeed if you have previously installed the required legacy versions of .NET Framework.
Caveat: While versions higher than v5.1 - the latest and last Windows PowerShell version - sensibly result in an error (the one you saw), unsupported lower versions are quietly ignored; in effect, -Version 1 and -Version 2 will both start version 2.0, whereas -Version 3, -Version 4 and -Version 5 are effectively ignored and run v5.1 - verify with $PSVersionTable.PSVersion
While a -Version parameter still exists in pwsh.exe, the PowerShell [Core] v6+ CLI, its meaning has changed:
It now simply reports a version number, namely the targeted executable's own (and therefore takes no argument).

Why doesn't Console in PowerShell ISE use the latest installed version of PowerShell?

I have recently installed PowerShell 6.2.
If I start a PowerShell 6 (x64) command prompt and run $PSVersionTable.PSVersion this is the result
Major Minor Patch PreReleaseLabel BuildLabel
----- ----- ----- --------------- ----------
6 2 0
From the same prompt I run the ISE using powershell_ise.exe and the PowerShell ISE starts. However, in the console within ISE if I run $PSVersionTable.PSVersion it reports this:
Major Minor Build Revision
----- ----- ----- --------
4 0 -1 -1
Is there a setting to control where ISE looks for PowerShell? Or is there any way to ensure it is using the latest version installed?
UPDATE: As part of installing PowerShell Core (i.e. ver 6.2) I had to install Windows Management Framework 5.1. My understanding from this doc is that this should have upgraded the ISE console's version of PowerShell to 5.1 as well. I am still seeing ver 4.0 as noted above. What am I missing?
The latest version of PowerShell is 5.1, this is the most recent version that you can use in ISE as well.
PowerShell 6 is also known as PowerShell Core, which is not supported in ISE. You can download a tool called Visual Studio Code that can be used with PowerShell 6 (Core).
Bonus:
Interestingly enough, there was actually an article I read recently about a PowerShell 7 that Microsoft is currently working on which looks pretty interesting. See here as well for PowerShell 7.
Update: Thanks #Magnetron for updating in the comments. PowerShell 7 officially released this week.
Hope this helps!
I used the following link to add an add-on to Powershell ISE that will allow you to switch between Powershell 5 and 6. (See 'PowerShell ISE Add-On Command’) However, when you close out of Powershell ISE and open a new session you have to run the script again otherwise the option 'Add-ons' will not be there. I'm guessing the same process could be used when Powershell 7 is released.
Using PowerShell Core 6 and 7 in the Windows PowerShell ISE
There's also a new feature in VSCode that emulates the ISE: https://devblogs.microsoft.com/powershell/visual-studio-code-for-powershell-7/
How to use ISE mode in VScode: https://www.thomasmaurer.ch/2020/03/how-to-use-powershell-ise-mode-in-visual-studio-code/
I would take a read of this guide - https://ironmansoftware.com/using-powershell-core-6-and-7-in-the-windows-powershell-ise/
It allows the ISE process to switch the backend PowerShell to be version 7. It even includes creation of a menu item and shortcut to swap the backend version. This is very handy and I have been using it with ISE for some time.
For those who wants a shorter version of enabling this.
Run this while in ISE (taken from the link from the other answers)
$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Clear()
$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Switch to PowerShell 7", {
function New-OutOfProcRunspace {
param($ProcessId)
$ci = New-Object -TypeName System.Management.Automation.Runspaces.NamedPipeConnectionInfo -ArgumentList #($ProcessId)
$tt = [System.Management.Automation.Runspaces.TypeTable]::LoadDefaultTypeFiles()
$Runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace($ci, $Host, $tt)
$Runspace.Open()
$Runspace
}
$PowerShell = Start-Process PWSH -ArgumentList #("-NoExit") -PassThru -WindowStyle Hidden
$Runspace = New-OutOfProcRunspace -ProcessId $PowerShell.Id
$Host.PushRunspace($Runspace)
}, "ALT+F5") | Out-Null
$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Switch to Windows PowerShell", {
$Host.PopRunspace()
$Child = Get-CimInstance -ClassName win32_process | where {$_.ParentProcessId -eq $Pid}
$Child | ForEach-Object { Stop-Process -Id $_.ProcessId }
}, "ALT+F6") | Out-Null
Then re-launch your ISE and go to Add-ons button next to File, Edit, View ant etc. There should be a Switch to Powershell 7 option now.
That's it! 1 min job.

Windows 8.1 Powershell Set-DisplayResolution

I found a technet article to set the display resolution using powershell and Windows Server Core Cmdlets. http://technet.microsoft.com/en-us/library/jj603036.aspx
However when I try to run the cmd PS C:\> Set-DisplayResolution -Width 1920 -Height 1200 I get an error saying the Set-DisplayResoluton is a unknown cmd. I know this cmd is for administering server core functionlaity but can it be used in Windows 8.1. And if so, how do I load the cmdlet in Powershell?
Are you trying to run this on Windows 8.1? It looks like the command might only be available on Windows Server 2012 R2 Server Core. I understand that the article says otherwise, but I just checked on my Windows 8.1 computers, and do not have the command in the session.
Get-Command -Name *resolu*;

Unable to add-pssnapin microsoft.exchange.management.powershell.admin to powershell studio script

Running powershell v2 with exchange management console 2007 installed.
a powershell prompt shows the registered snapings:
PS P:\> get-pssnapin -registered | fl name
Name : Microsoft.Exchange.Management.PowerShell.Admin
Name : Microsoft.Exchange.Management.Powershell.Support
I can run exchange related commands from a powershell prompt, however, powershell studio 2012 doesnt seem to recognize the addin. In my _load method, I have
Add-PSSnapin Microsoft.Exchange.Management.Powershell.admin
But get this when I run the script:
ERROR: Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 2.
Powershell studio is the trial version and running v2 as well.
Maybe some snappins do not load with the trial?
You problem may come from the fact that PrimalScript 2012 and PowerShell Studio 2012 are 32 bit executables.
Have you got the two modes allowed in PowerShell Studio 2012 ?

How do I get PowerShell 4 cmdlets such as Test-NetConnection to work on Windows 7?

The situation. On a Windows 7 SP1 machine, I have updated with Windows6.1-KB2819745-x64-MultiPkg.msu. Furthermore, in PowerShell $PSVersionTable now reports ‘PSVersion 4.0’.
At present, my conclusion is that many PowerShell 4 cmdlets such Test-NetConnection, will only work on Windows 8.1. However, I was wondering if there was a work-around whereby I could import PowerShell 4 modules on my Windows 7 machine.
You cannot. They rely on the underlying features of the newer OS (8.0 or 8.1) and cannot be ported back to Windows 7 . The alternative is to write your own functions / modules to replicate the new cmdlets using .NET framework methods.
For instance, the Get-FileHash cmdlet is a one-liner in PowerShell 4.0, but to replicate in 2.0 we have to use .NET.
PowerShell v4
Get-FileHash -Algorithm SHA1 "C:\Windows\explorer.exe"
PowerShell v2
$SHA1 = new-object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider
$file = [System.IO.File]::Open("C:\Windows\explorer.exe",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)
[System.BitConverter]::ToString($SHA1.ComputeHash($file)) -replace "-",""
$file.Close()
At least Test-NetConnection can be ported back to Windows 7. Just copy folders NetTCPIP, DnsClient, and NetSecurity from the supported Windows machine with the same PowerShell version (Windows 8.1, Windows 10, etc). Folder - C:\Windows\System32\WindowsPowerShell\v1.0\Modules. Then Import-Module -Name C:\Windows\System32\WindowsPowerShell\v1.0\Modules\NetTCPIP -Verbose
Alternatively, you can import a module from a remote machine (say win2012):
$rsession = New-PSSession -ComputerName win2012
Import-Module NetTCPIP -PSSession $rsession
I have had the same problem on my Windows 7 x64 and both solutions worked for me as of PowerShell 5.1.
Adding to Anton Krouglov's answer. PowerShell modules are cross-platform compatible. So a module copied from Windows Server 2012 R2 x64 can be imported to Windows 7 x86, and even if you are running as standard user without rights to copy them to C:\Windows\System32\WindowsPowerShell\v1.0\Modules you can copy it to any local folder, and run.
Assuming you copied the NetTCPIP, DnsClient, and NetSecurity modules from a Windows Server 2012 or higher machine, and save them to a folder you can import them using
Get-ChildItem -Directory .\psmodules | foreach { Import-Module -Name $_.FullName -Verbose}
Test-NetConnection -InformationLevel "Detailed"
As far as I know, Windows Server 2008 R2/Windows 7 simply doesn't have the counters that the .NET methods use to implement get-netstuff.
A new PowerShell version can implement hash compare, etc. since this is not related to anything, just a piece of code. But if you want to use, for example, Get-NetTCPConnection there is nothing to show.
I see several responses which assert portability, and my testing confirms their assertions:
Import all of the required modules, either from file, or via a PSSession to a host which has the required modules.
The architecture of PowerShell Console (x86 or x64) you run will determine which module architecture you import.
For those who are:
still unable to make this work
AND
do need a reliable TCP test, but may not need everything else provided by Test-NetConnection
AND
Need it all to work even on PowerShell v2.0
You may wish to try this.
# Create a TCP Client using .Net & attempt connection to target
$TCPClient = New-Object .net.sockets.tcpclient("[IP address or hostname]",[port])
# At the above point you may see familiar-looking Windows error messages in
# red text. (You may want to use "try/catch" if you intend to loop).
# Otherwise, check your new object's status to see if it worked
$TCPClient.Connected
# The response is either "True" or False"
# Now to avoid leaving idle connections, run:
$TCPClient.Close()
Naturally, it should be possible to create a loop which tests multiple connections, and outputs the results by selecting the properties of the $TCPClient.
My initial testing shows you would want to Select these properties
The address you tested
$TCPClient.Client.RemoteEndPoint.Address.IPAddressToString
The port you tested
$TCPClient.Client.RemoteEndPoint.Port
The result
$TCPClient.Connected
HIH
While PowerShell 4.0 is available on Windows 7, as Knuckle-Dragger states certain features rely on newer operating system functionality. Unfortunately Test-NetConnection is not available in Windows 7 as stated in the documentation.
Test-Connection, which is present, is basically ping. Test-NetConnection offers much more functionality, allowing a choice of things such as TCP ports, protocols, route tracing, and information levels.
There is a Send-Ping script available from the ScriptCenter in the TechNet gallery, but I think this is only really useful if you are stuck on PowerShell 3.0 for some reason.
I can only assume you installed the wrong package. Make sure you download the proper package from here.
Below you will see in running Windows 7 Service Pack 1 with PowerShell 4 using Test-Connection and Get-FileHash: