Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running PSScriptAnalyzer on nanoserver #984

Closed
mlocati opened this issue May 5, 2018 · 15 comments · Fixed by #990
Closed

Running PSScriptAnalyzer on nanoserver #984

mlocati opened this issue May 5, 2018 · 15 comments · Fixed by #990

Comments

@mlocati
Copy link

mlocati commented May 5, 2018

PSScriptAnalyzer does not currently run on nanoserver.

Try this command on a Windows machine with Docker installed (and configured to run Windows containers):

docker run --rm --tty microsoft/nanoserver powershell.exe "Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force | Out-Null; Install-Module PSScriptAnalyzer -Force; Get-Module -ListAvailable | Where-Object { $_.Name -eq 'PSScriptAnalyzer' }; Set-Content -Value 'Write-Output ''test''' -Path test.ps1; Invoke-ScriptAnalyzer -Path test.ps1"

The output will be

    Directory: C:\Program Files\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.16.1     PSScriptAnalyzer                    {Get-ScriptAnalyzerRule, Invoke-ScriptAnalyzer, Invoke-Formatter}
Invoke-ScriptAnalyzer : Could not load type 'System.Management.Automation.SemanticVersion' from assembly 'System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
At line:1 char:257
+ ... Output ''test''' -Path test.ps1; Invoke-ScriptAnalyzer -Path test.ps1
+                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-ScriptAnalyzer], TypeLoadException
    + FullyQualifiedErrorId : System.TypeLoadException,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand

The only relevant info I found about running PSScriptAnalyzer on NanoServer is located at https://github.com/PowerShell/PSScriptAnalyzer/blob/NanoServer/ExtraStepsSettingUpNanoServerScriptAnalyzer.md , but it seems quite outdated and unmaintained.

@bergmeister
Copy link
Collaborator

bergmeister commented May 5, 2018

Thank you for reporting this.
Without having investigated it yet, there is a chance that this might be already fixed or at least improved in the upcoming release of 1.17 (hopefully next week) because the references to SMA are now properly configured, therefore I'd like to wait for the results with the new release if that is OK with you? I could already give you a preview (i.e. unsigned) version of it if you want?

By looking at your referenced document, I do not think/hope that you need to compile PSSA yourself but the instructions say so.

Can you also print the output of $PSVersionTable please? If I remember correctly, then NanoServer has a custom version 6 of Windows PowerShell in it. I know there is custom code in PSSA for Windows PowerShell vs PowerShell Core and I imagine it thinks it is a core version because of the 6 in the version and then calls the wrong api...

Out of interest: Are you using PSSA in NanoServer as part of testing phase of your CI process or is there a different reason why you need to use it on NanoServer?

@mlocati
Copy link
Author

mlocati commented May 5, 2018

Without having investigated it yet, there is a chance that this might be already fixed or at least improved in the upcoming release of 1.17 (hopefully next week) because the references to SMA are now properly configured, therefore I'd like to wait for the results with the new release if that is OK with you? I could already give you a preview (i.e. unsigned) version of it if you want?

No hurry at all... I'm going to use PSScriptAnalyzer to run Appveyor tests for a package I'm developing.
I'm planning to run these tests both on the default Appveyor Windows Server and in a Docker image with nanoserver. Of course, for the time being I can skip the PSScriptAnalyzer tests on nanoserver (since they are executed on the Windows Server).

Can you also print the output of $PSVersionTable please? If I remember correctly, then NanoServer has a custom version 6 of Windows PowerShell in it.

Sure! Here it is:

C:\>docker run --rm --tty microsoft/nanoserver powershell.exe $PSVersionTable
Name                           Value
----                           -----
PSRemotingProtocolVersion      2.3
BuildVersion                   10.0.14393.1000
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
PSEdition                      Core
CLRVersion
PSVersion                      5.1.14393.1000
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}

@mlocati
Copy link
Author

mlocati commented May 5, 2018

PS:

C:\>docker images -a
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
microsoft/nanoserver   latest              353592ac9faa        3 weeks ago         1.11GB

C:\>docker pull microsoft/nanoserver
Using default tag: latest
latest: Pulling from microsoft/nanoserver
Digest: sha256:59558bd57c0d14a4df5b827a676fb061abacefebfa2089038f018cf9eea17ecb
Status: Image is up to date for microsoft/nanoserver:latest

@bergmeister
Copy link
Collaborator

bergmeister commented May 5, 2018

Thanks. Aha, the PSVersionTable reveals that it is actually a (custom pre-release) version of PowerShell Core but of version 5.1 (really confusing versioning but I guess the PowerShell team was asked to quickly give out something that works on NanoServer..).
I will setup Docker on an Azure VM in the next days and play with it a bit to give you a more detailed answer/solution.

@bergmeister
Copy link
Collaborator

bergmeister commented May 5, 2018

P.S. For the moment, I am not sure if PSSA is currently supported or supposed to work on NanoServer as-is since your referenced branch seems to be rather an old PoC. But anyway, I will try to make it work on it.

mlocati added a commit to mlocati/powershell-phpmanager that referenced this issue May 5, 2018
@mlocati
Copy link
Author

mlocati commented May 5, 2018

Thank you, Christoph.

For the time being I just excluded PSSA from my tests on nanoserver (see https://ci.appveyor.com/project/mlocati/powershell-phpmanager/build/Build%2097 ).

@bergmeister
Copy link
Collaborator

bergmeister commented May 6, 2018

Some minor updates, I can repro now (even when I use -Scope CurrentUser for installation, since some images have issues with not using that option) and the full stack trace is (using $error[0] | select *):

Exception             : System.TypeLoadException: Could not load type 'System.Management.Automation.SemanticVersion' from assembly
                        'System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
                           at Microsoft.Windows.PowerShell.ScriptAnalyzer.PSVersionTable..ctor(Hashtable psVersionTable)
                           at Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper.SetPSVersionTable(Hashtable psVersionTable)
                           at Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand.BeginProcessing()
                           at System.Management.Automation.Cmdlet.DoBeginProcessing()
                           at System.Management.Automation.CommandProcessorBase.DoBegin()

This is happening here because it seems that the SemanticVersion class is not present in this version of PowerShell Core (maybe hence why they used 5.1 as a version for it as it seems to be a stripped version of Windows PowerShell but running on .Net Core). One can also verify this using docker run --rm --tty microsoft/nanoserver powershell.exe "[System.Management.Automation.SemanticVersion]'1.2.3'", therefore the current version is definitely not compatible with the nanoserver image.
I was playing a bit around with the other Docker images and it seems the microsoft/powershell image (which has the latest version of PsCore) are only Linux images. Would that be a viable alternative to use that (since PSSA works on Linux) or the (bigger) microsoft/windowsservercore image before I start looking into fixing it? In the meantime a logged the following bug for the nanoserver-insider-powershell image: PowerShell/PowerShell#6826
For the moment what I tested and works is the windowsservercore image

docker run  --rm --tty microsoft/windowsservercore powershell "Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force | Out-Null; Install-Module PSScriptAnalyzer -Force; Get-Module -ListAvailable | Where-Object { $_.Name -eq 'PSScriptAnalyzer' }; Set-Content -Value 'Write-Output ''test''' -Path test.ps1; Invoke-ScriptAnalyzer -Path test.ps1"

Or alternatively in Linux mode the powershell image works as well:

docker run --rm --tty microsoft/powershell pwsh -c "Install-Module PSScriptAnalyzer -Force; Get-Module -ListAvailable | Where-Object { $_.Name -eq 'PSScriptAnalyzer' }; Set-Content -Value 'Write-Output ''test''' -Path test.ps1; Invoke-ScriptAnalyzer -Path test.ps1"

@mlocati
Copy link
Author

mlocati commented May 7, 2018

I was playing a bit around with the other Docker images and it seems the microsoft/powershell image (which has the latest version of PsCore) are only Linux images. Would that be a viable alternative to use that (since PSSA works on Linux) or the (bigger) microsoft/windowsservercore image before I start looking into fixing it?

Not for me: the PSGallery package I'm developing is meant to work only on Windows (it's used to install/update/configure PHP on Windows).

@bergmeister
Copy link
Collaborator

Hmm, ok. For the moment, it seems you can only use it using the windowsservercore image on Windows but I will try to get NanoServer support in as well.

@bergmeister
Copy link
Collaborator

bergmeister commented May 7, 2018

Note that I found that some of the docs on the PowerShell repo seem to be out of date as well. For example they refer to the microsoft\nanoserver-insider-powershell image, which hasn't been updated for 9 months. I found that the microsoft\powershell image has also other tags with the latest nanoserver images with the latest version of PowerShell Core. However, when trying those, I ran into other problems with bootstrapping the NuGet package provider and PowerShellGet...
I will keep you updated, but I imagine doing a volume mapping or just downloading PSSA via the REST Api of the PsGallery and then setting the $env:Psmodulepath should make it work then.
Can someone from the PowerShell team comment on the recommendation for a good image and best practices or known issues? Cc @SteveL-MSFT

@mlocati
Copy link
Author

mlocati commented May 7, 2018

Thank you Christoph,

BTW I didn't file this issue for my own needs: in my repo I'm testing two different environments, one being a standard Windows server image, the other being a nanoserver docker image.
I already execute PSSA in the first image, so these tests aren't strictly needed in the second image.

I filed this issue for the sake of completeness of this great PSSA (it should run on as many platform as possible), for other developers, and for myself if in future I'll write some code that will be tested only on nanoserver.

@SteveL-MSFT
Copy link
Member

@TravisEz13 had deprioritized getting a new image of nanoserver+PSCore6 out since we're in process of rebuilding our docker image creation

@bergmeister
Copy link
Collaborator

bergmeister commented May 7, 2018

@mlocati Instead of installing it, I just download the module and import it then. You will see a warning message ( Win32Helpers: Cannot add type. Compilation errors occurred.) from Save-Module but you can ignore it since it is still able to get the job done. Here is the working example:

docker run -it microsoft/powershell:nanoserver pwsh -c "Save-Module -Name PSScriptAnalyzer -Path .; Import-Module C:\PSScriptAnalyzer; Invoke-ScriptAnalyzer -ScriptDefinition 'gci'"

This Docker image contains the 1709 Windows build (10.0.16299) and PowerShell Core 6.0.2
There are also other tags like 6.0.2-nanoserver and 6.0.2-nanoserver-1709 but it seems that those are all identical at the moment (I think with the idea that the nanoserver image would always be updated with the latest version of pwsh or Windows). I guess, this means it is better to use the microsoft/powershell:nanoserver instead of the microsoft/nanoserver then due it having the latest version of PowerShell Core, the image is also only 179 MB vs 408 MB, does this mean the PowerShell NanoServer image is missing some functionality compared to the normal NanoServer image @TravisEz13
Please correct me if I'm wrong in any of those statements @SteveL-MSFT

@mlocati
Copy link
Author

mlocati commented May 8, 2018

@bergmeister Thanks for the deep analysis.

BTW I'll continue using microsoft/nanoserver because:

  • I already run PSSA tests (not on nanoserver but on a full Windows server)
  • I'm developing a package that's meant to run on as many target environment as possible, and microsoft/nanoserver seems to have a lower PS version.

@TravisEz13
Copy link
Member

@bergmeister Our image is based on microsoft\nanoserver:1709 (newer than latest.) There are breaking changes which make this image much smaller, but I would recommend starting with this images as these changes are already announced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants