Repository: microsoft/terminal (language: cpp)

Issue:
Check powershell version before building 
# Description of the new feature/enhancement

When trying to build for the first time, if the wrong version of PowerShell is installed, the build fails without a clear error message detailing the issue. For the sake of developers new to the project, an error message pointing out the incorrect version of PowerShell could be very helpful. 

This is my first time contributing, so any feedback is welcome! I would also like to try and implement this if that's alright.


Discussion / hints:
To add some more info: when building for the first time, I had Windows Powershell installed, which I thought was the version I needed. The build failed, with 6 different Projects failing to build. 

![console](https://user-images.githubusercontent.com/81830231/217281724-d8937453-72b2-4445-b349-4a7eb4f0ce51.PNG)
(Note: In this image, I ran it as AnyCPU instead of x64. When I ran it as x64 before I downloaded the correct version of PowerShell, I got the same errors.)

I thought I had the correct version of PowerShell installed, but what tipped me off was this line:
![image](https://user-images.githubusercontent.com/81830231/217282837-183fd0df-9f3e-4bf4-9796-179ae2a8c6fb.png)

I downloaded PowerShell 7.3.2, restarted Visual Studio, and it built without issue. I think it would be a good idea for new users to have a more clear error stating that the version of PowerShell is incorrect, so it would be helpful if there was a pre-build check to see what version of PS is installed and an error message if the version installed is incorrect. 

I'm new to the project and to open source, so any advice or feedback would be welcome. As I said, I would love to tackle this issue if possible.
> I'm new to the project and to open source, so any advice or feedback would be welcome. As I said, I would love to tackle this issue if possible.

We would love to accept a contribution for this!

A good first step would be to find the vcxproj file that uses pwsh to see if any improvements can be made in there. 
@Smeyer025 are you still working on this ? 
@carlos-zamora @zadjii-msft  I was able to find file which is `Microsoft.Terminal.Settings.ModelLib.vcxproj` . I have not run this project in my local system yet. Now the line 334 seems to be in question (as in the screenshot) which is a comment(How can a comment give error ?).
Now where do I have to go from here . Suggest some things that I need to learn to proceed.  I already read the CONTRIBUTING.md .
@heysujal I am still working on this, and I think I have a solution. Here's what I have so far:
![image](https://user-images.githubusercontent.com/81830231/222504322-ce263214-b591-4fb1-888d-0fe97b1e3981.png)
This error occurs because PowerShell Core (v7 or above, as stated in the prerequisites) is not installed. That being said, my issue when building initially was that I had Windows PowerShell 5.1 installed, and though the command to find the version is the same in both PowerShell Core and Windows PowerShell (`$PSVersionTable`, or `$PSVersionTable.PSVersion.Major` to be more specific), the name of the .exe file is different between Windows and Core. For Windows PowerShell, it is powershell.exe as opposed to pwsh.exe for Core. Here's what I propose as a solution, that I have implemented in the .vcxproj file: 
![image](https://user-images.githubusercontent.com/81830231/222509612-3d40b77b-7759-4958-be6e-90822747200b.png)
What this does is it calls scripts I wrote that check the version of PowerShell installed. For pwsh.exe (PowerShell Core), if the version installed is less than 7.0.0, it writes an error and exits. But, for powershell.exe (Windows Powershell), it only checks to see if it is installed. If it is installed, it writes an error directing the user to install PowerShell Core, but will not exit, in case the user has both Core and Windows installed. Here are the exact scripts:
CheckPSVersion.ps1:
```
if($PSVersionTable.PSVersion.Major -lt 7){
   Write-Error "Incorrect version of PowerShell installed.`nMake sure you have at least PowerShell Core 7.0.0."
   Exit 1 
}
```

WindowsCheckPSVersion.ps1
```
if($PSVersionTable.PSVersion.Major -le 5){
   Write-Error "Make sure you have at least PowerShell Core 7.0.0."
}
```
(Note: I chose not to have WindowsCheckPSVersion.ps1 exit because if a user has both Windows and Core installed, it would exit even though there would be no issues building)

When building with these scripts here are the different cases I validated:
**Core 7.3.2 and Windows 5.1 installed**: built without issue, an error was printed to ensure that Core 7.0.0 or above was installed.
**Core installed, but not Windows**: built without issue; threw an error that "powershell.exe" (Windows Powershell) was not recognized.
**Windows installed, but not Core**: Build failed, but the user is instructed to download Core by WindowsCheckPSVersion.ps1
**Neither Core nor Windows installed**: Build failed, both commands fail because pwsh.exe and powershell.exe are both not recognized. But, it is easier to decipher for newer users because there is an explicit error saying "powershell.exe" is not recognized, so at worst, someone might download Windows PowerShell, which would lead to one of the above cases on rebuild. 

@carlos-zamora @zadjii-msft I would love some feedback on this solution, so any comments or concerns would be much appreciated. If this solution is good enough for a pull request, let me know and I will submit one immediately. Thanks!

Hmm. That seems like a good start, though I'm a little worried that even in the case where pwsh 7 is installed, we still print an error message. 

Maybe it'd just be possible to check in the `WindowsCheckPSVersion.ps1` script if `pwsh` is installed on the path, and then print the error and bail if we fail to find it? My PowerShell-fu is notoriously the weakest of anyone on the team, but maybe something like:

```ps1
if (Get-Command "pwsh.exe" -ErrorAction SilentlyContinue) {
  "yep"
} else { 
  Write-host "nope"
}
```
![image](https://user-images.githubusercontent.com/18356694/222576801-2a7212e5-2c41-49c7-afb6-70a0342a62c6.png)

@zadjii-msft Thanks for the feedback! I changed `WindowsCheckPSVersion.ps1` to be:
```
if(-not (Get-Command "pwsh.exe" -ErrorAction SilentlyContinue)){
    Write-Error "Incorrect version of PowerShell installed.`nMake sure you have at least PowerShell Core 7.0.0."
}
```
This now only outputs an error if Windows PowerShell is installed and PowerShell Core is not. 

Now, the updated build for the cases from before:
**Core 7.3.2 and Windows 5.1 installed:** built without issue, no erroneous errors
**Core installed, but not Windows:** built without issue; threw an error that "powershell.exe" (Windows Powershell) was not recognized.
**Windows installed, but not Core:** Build failed, and the user is instructed to download Core by WindowsCheckPSVersion.ps1
**Neither Core nor Windows installed:** Build failed, both commands fail because pwsh.exe and powershell.exe are both not recognized. But, it is easier to decipher for newer users because there is an explicit error saying "powershell.exe" is not recognized, so at worst, someone might download Windows PowerShell, which would lead to one of the above cases on rebuild.

Thanks so much for the quick response! I would love feedback on my updated script, and thanks again!
Seems good to me! Looking forward to the PR ☺️ 
> Seems good to me! Looking forward to the PR ☺️

Awesome, I'll start working on that right now! 

Fix patch:
diff --git a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj
index 1df61875440..8ee88a2c018 100644
--- a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj
+++ b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj
@@ -325,6 +325,13 @@
   <Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
   <Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
 
+  <!-- PowerShell version check, outputs error if the wrong version is installed. -->
+  <Target Name="_WindowsPowershellVersionCheck" BeforeTargets="BeforeClCompile">
+    <Exec Command="powershell.exe -NoProfile -ExecutionPolicy Unrestricted &quot;$(OpenConsoleDir)\tools\WindowsCheckPSVersion.ps1&quot;" />
+  </Target>
+  <Target Name="_PowershellVersionCheck" BeforeTargets="BeforeClCompile">
+    <Exec Command="pwsh.exe -NoProfile -ExecutionPolicy Unrestricted &quot;$(OpenConsoleDir)\tools\CheckPSVersion.ps1&quot;" />
+  </Target>
   <!-- This target will take our defaults.json and stamp it into a .h file that
   we can include in the code directly. This way, we don't need to worry about
   failing to load the default settings at runtime. -->
diff --git a/tools/CheckPSVersion.ps1 b/tools/CheckPSVersion.ps1
new file mode 100644
index 00000000000..ffde273393b
--- /dev/null
+++ b/tools/CheckPSVersion.ps1
@@ -0,0 +1,4 @@
+if($PSVersionTable.PSVersion.Major -lt 7){
+   Write-Error "Incorrect version of PowerShell installed.`nMake sure you have at least PowerShell Core 7.0.0."
+   Exit 1 
+}
\ No newline at end of file
diff --git a/tools/WindowsCheckPSVersion.ps1 b/tools/WindowsCheckPSVersion.ps1
new file mode 100644
index 00000000000..cc2b78dbeba
--- /dev/null
+++ b/tools/WindowsCheckPSVersion.ps1
@@ -0,0 +1,3 @@
+if(-not (Get-Command "pwsh.exe" -ErrorAction SilentlyContinue)){
+    Write-Error "Incorrect version of PowerShell installed.`nMake sure you have at least PowerShell Core 7.0.0."
+}
\ No newline at end of file


Test patch: