Powershell: #Requires -Edition (Desktop | Core)

Created on 15 Jan 2018  路  13Comments  路  Source: PowerShell/PowerShell

Dear team,
please consider adding #Requires -Edition (Desktop | Core) statement for scripts that are not compatible with Core and still requires Desktop version to run.

It would be great to write

#Requires -Edition Desktop

instead of

if($PSVersionTable.PSEdition -eq 'Core')
{
    throw "Doesn't work with PowerShell Core. Please use Windows PowerShell."
}    
Issue-Question Resolution-Answered

All 13 comments

You could use the following PowerShell Core Is* variables to accomplish the result you're asking. As, if you query for these variables, then you can add the logic to either run in Windows PowerShell or PowerShell Core.

PS C:\Program Files\PowerShell\6.0.0> Get-Variable Is*

Name                           Value
----                           -----
IsCoreCLR                      True
IsLinux                        False
IsMacOS                        False
IsWindows                      True

On the other hand, I'm sure you can use the "#Requires -Version 6", as this will prevent to run it on Windows PowerShell.

:)

Yes, but #Requres is more pretty thing. :) All in all, that's why we have it.
The question is not in how to tell a script to run only on version 6 and higher (#Requires -Version 6 will help with that), the question is how to tell a script to run only on PSEdition=Desktop and PSVersion from 3.0 to 5.1 and not on PSEdition=Core.
This is useful when a script has code that can't be executed in PS Core and we can't handle it with module references, like [adsi] or usage of .NET Framework classes that don't exist in .NET Core.

Btw, $IsCoreCLR doesn't exist in early versions.

PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.16299.98
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.16299.98
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


PS C:\> $IsCoreCLR
The variable '$IsCoreCLR' cannot be retrieved because it has not been set.
At line:1 char:1
+ $IsCoreCLR
+ ~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (IsCoreCLR:String) [], RuntimeException
    + FullyQualifiedErrorId : VariableIsUndefined

Understood!

I know $Is* variables doesn't exist in Windows. That's why in my case, I would add the condition if it doesn't exist, then use the logic to run the code in Windows PowerShell. This way the script could be execute on either existing version.

But, I'm looking for cross-platform scripting where I can have the code run on either version of PowerShell.

I know the possibility are endless and it will continue to evolve.

I'm dare to say that version 6 (and above) will be Core all the way.

:)

...and what your script will do if somewhere in the future it will be run in some desktop *nix ISE, without support for some win/full .NET functionality?
:)

@al-ign What if somewhere in the future in a far-far away galaxy are not the questions I'm targeting.
From now, many of regular PS users can and definitely will face the situation when they have 2 PS versions installed side by side on one machine. These users already have their own script libraries that were written for Windows PowerShell and designed to manage only Windows environments.
If such script will be executed on PS Core 6 it will fail somewhere in the middle when PS will find something unsupported (remember, script was build and debugged on Windows PS). This can leave the system it is designed to manage in a non consistent state - half of the cmdlets were executed, the half were not. This is potentially a dangerous situation. Actually, this why we have #Requires statement at all.

+1 to @dronkoff - ".. #Requires.."statement will be needed in such a case.

But, that will be the task (and responsability) of the Admin scripter to adopt the new way of handling/manage scripts across platforms. And, I would include any third-party entities producing PowerShell modules.

In this scenario, source control tools will become beneficial and important to be adopted by everyone.

:)

I agree, such statement would be useful.

Is this already in PowerShell as #requires -PSEdition? I found this documentation, and this check in the PowerShell source.

I've opened an RFC on updating the behaviour of #requires. Please feel free to comment in the PR.

Trying to figure out what #requires extensions would be meaningful, it came to me, what an additional statement could be also usefull: #testedon (or #testedfor, or just #tested).

To give you some context: my main non-Windows OS distribution is CentOS, so I'm writing scripts with CentOS-specific nuances. I wrote some scripts with Debian/Ubuntu compatibility in mind (httpd vs apache, for example), but they never been tested on it on any meaningfull extent.

While #requires prohibits running on not supported environment, the best part in it is what it could be analyzed even without running the script.
So, #tested could be used as indication if current environment is tested one for execution (maybe we will have some Test-ScriptCompatibility cmdlet someday?), without even running script.
Also PS engine could emit warning/verbose/debug message, if current environment is not supported, warning user about possible incompatibilites.

I would like to hear your opinion on this idea (especially @dronkoff), so if it is as good as I imagine - I will create separate thread for a more broad discussion.

@al-ign please feel free to write any suggestions for extending #requires as comment on the RFC linked above (by commenting on the PR). If there are features you would like included for #requires, that's probably the best place to raise them.

This would be useful for something like AWS Lamda to parse out which powershell the script should be run with.

PowerShell Core (and Windows PowerShell) already support this actual feature.

#requires -PSEdition Core

Write-Output 'Hello'

See this comment as well: https://github.com/PowerShell/PowerShell/issues/5908#issuecomment-375543426

I'm guessing I left the issue open for discussion before, but closing now since the ask has been in PowerShell for a while.

Was this page helpful?
0 / 5 - 0 ratings