[英]Evaluate current PowerShell session version from C# class during script module import
首先,我正在嘗試做的一些背景。 我正在編寫一個 PowerShell 腳本模塊,該模塊需要在導入模塊時設置一些變量並運行一些代碼。 最終需要發生的事情取決於導入模塊的 PowerShell 版本。 比如這個需要支持5.1及以后,但是Invoke-RestMethod
不支持
-SkipCertificateCheck
參數直到 PowerShell 6,這意味着我需要檢查版本,創建一個虛擬的 ICertificatePolicy ,它在驗證時基本上總是返回true
,並將其存儲在一個全局位置,我可以引用它並設置該策略,如果用戶要求他們想要調用某些 cmdlet 時跳過安全檢查。 到目前為止,我有以下代碼:
Add-Type @"
using System.Management.Automation;
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace MyModuleNamespace {
public struct State {
public static ICertificatePolicy SystemCertificatePolicy;
public static ICertificatePolicy SkipSSLCheckPolicy;
}
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
}
namespace MyModuleNamespace.SubNamespace {
public class ModuleAssemblyInitializer : IModuleAssemblyInitializer {
public void OnImport() {
// pseudocode of what I'm struggling to define in C#
if( CurrentPSSession.PSVersion.Major -lt 6 ) {
MyModuleNamespace.State.SystemCertificatePolicy = ServicePointManager.CertificatePolicy;
MyModuleNamespace.State.SkipSSLCheckPolicy = new MyModuleNamespace.TrustAllCertsPolicy();
}
// end pseudocode
}
}
}
"@
但是......我正在努力評估當前 PowerShell 會話中的信息,例如評估$PSVersionTable.PSVersion
。 我知道如何檢查安裝了哪些 PowerShell 版本,但我需要能夠評估添加了此類的 PowerShell 當前運行版本。 此外,我不希望整個模塊都用 C# 編寫,即使這在技術上是一種選擇。 我團隊中的其他人將需要維護該模塊,雖然他們非常了解 PowerShell,但 C# 超出了他們的技能范圍。
如果有一種 PowerShell 本地方式來處理導入模塊時運行代碼的情況,我完全聽得懂。 這是我的第一個 PowerShell 模塊,如果我使用錯誤的解決方案來解決這個問題,我不會感到驚訝。
一般來說,我強烈建議根本不要這樣做。 盲目跳過證書信任驗證是一個壞主意。
正如我(不好)試圖在評論中解釋的那樣,如果您解析調用程序集(即System.Management.Automation.dll
),您可以使用它來使用反射發現初始化程序中的版本信息:
using System;
using System.Management.Automation;
using System.Reflection;
namespace CrossVersionModule
{
public class ModuleAssemblyInitializer : IModuleAssemblyInitializer
{
public void OnImport()
{
// obtain reference to calling assembly
var caller = Assembly.GetCallingAssembly();
// locate the PSVersionInfo type
var psversionType = caller.GetType("System.Management.Automation.PSVersionInfo");
if (null != psversionType)
{
// locate the PSVersion property
PropertyInfo versionProp = psversionType.GetProperty("PSVersion");
if (null == versionProp) {
// In .NET framework (ie. Windows PowerShell 5.1) we have to explicitly pass binding flags for non-public members
versionProp = psversionType.GetProperty("PSVersion", BindingFlags.NonPublic | BindingFlags.Static);
}
// Invoke the getter to get the value
var getter = versionProp.GetGetMethod(true);
var version = getter.Invoke(null, new object[] { });
Console.WriteLine(version); // here's where you'd do your version check
}
}
}
}
如果我針對PowerShell Standard編譯上述內容,則分別在 5.1 和 7 中導入時會獲得正確的 PowerShell 版本
除了 Mathias 的有用答案之外,我還找到了一些方法來確定 .NET 版本。
一種是擴展字符串中的表達式,並將以下代碼添加到我的struct State
以將$PSVersionTable.PSVersion
的值插入到 C# 代碼中,然后可以在模塊代碼的其他地方讀取這些值:
public struct State {
public static ICertificatePolicy SystemCertificatePolicy = ServicePointManager.CertificatePolicy;
public static ICertificatePolicy SkipSSLCheckPolicy;
// Lines below were added
public readonly static System.Version PSVersion;
static State() {
PSVersion = new Version(
$($PSVersionTable.PSVersion.Major),
$($PSVersionTable.PSVersion.Minor),
$($PSVersionTable.PSVersion.Build),
$($PSVersionTable.PSVersion.Revision)
);
}
}
另一種有效的方法是檢查調用程序集的 product 屬性的值,它可以為調用程序集上的AssemblyProductAttribute
返回一些內容之一:
Microsoft® .NET Framework
如果使用 Windows PowerShell)Microsoft® .NET Core
如果使用 PowerShell CoreAdd-Type
在 PowerShell 腳本中編譯的 C# 調用
Microsoft (R) Windows (R) Operating System
如果在 .NET Framework 上)PowerShell
在我的情況下,我可以檢查屬性是否等於PowerShell
以查看這是否是 .NET Core:
// New using directives
using System;
using System.Reflection;
// Check if .NET Core
AssemblyProductAttribute attribute = Attribute.GetCustomAttribute(Assembly.GetCallingAssembly(), typeof(AssemblyProductAttribute)) as AssemblyProductAttribute;
if(attribute.Product == "PowerShell")) {
// do .NET Core things
}
似乎第三種方法在運行時有一些問題,我已經從這個答案中刪除了它,直到我弄清楚發生了什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.