提问人:Danny 提问时间:11/7/2023 最后编辑:Danny 更新时间:11/8/2023 访问量:88
使用证书时 PowerShell 5.1 和 7 之间的区别
Difference between PowerShell 5.1 and 7 when working with certificates
问:
下面是我正在制作的脚本的一小部分。我需要它在 PowerShell 5.1 中工作 目前它仅适用于 PS7。我安装了软件包“System.IdentityModel.Tokens.Jwt 7.0.3”,并在脚本文件夹中复制了我正在引用的dll。 当我在 PS7 中运行此脚本时,我从“new-object Microsoft.IdentityModel.Tokens.X509SigningCredentials($x 509cert)”中输出 在 PS5.1 上,我收到错误:
System.Management.Automation.MethodInvocationException: Exception calling ".ctor" with "1" argument(s): "The type initializer for 'PerTypeValues`1' threw an exception." ---> System.TypeInitializationException: The type initializer for 'PerTypeValues`1' threw an exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
at System.SpanHelpers.PerTypeValues`1.MeasureArrayAdjustment()
at System.SpanHelpers.PerTypeValues`1..cctor()
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Tokens.Base64UrlEncoder.Encode(Byte[] inArray, Int32 offset, Int32 length)
at Microsoft.IdentityModel.Tokens.X509SecurityKey..ctor(X509Certificate2 certificate)
at Microsoft.IdentityModel.Tokens.SigningCredentials..ctor(X509Certificate2 certificate)
at Microsoft.IdentityModel.Tokens.X509SigningCredentials..ctor(X509Certificate2 certificate)
--- End of inner exception stack trace ---
at System.Management.Automation.DotNetAdapter.AuxiliaryConstructorInvoke(MethodInformation methodInformation, Object[] arguments, Object[] originalArguments)
at System.Management.Automation.DotNetAdapter.ConstructorInvokeDotNet(Type type, ConstructorInfo[] constructors, Object[] arguments)
at Microsoft.PowerShell.Commands.NewObjectCommand.CallConstructor(Type type, ConstructorInfo[] constructors, Object[] args)
有人可以向我解释 5.1 和 7 除了 .NET 版本之外有什么区别吗?为什么这段代码不能在 5.1 上运行?
$CertPassWord = "password" # Password used for creating the certificate
$CertificatePath_Pfx = "C:\Temp\Certs\test.pfx" # Path where the certificate is saved
[System.Reflection.Assembly]::LoadFrom("C:\Temp\Certs\Microsoft.IdentityModel.Tokens.dll")
$x509cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2($CertificatePath_Pfx, $CertPassWord)
new-object Microsoft.IdentityModel.Tokens.X509SigningCredentials($x509cert)
答:
平台兼容性...
PowerShell 5.1:
它是内置于 Windows 中的 PowerShell 版本,可在所有 Windows 系统(从 Windows 7 开始)上使用。它主要面向 Windows 环境。
PowerShell 7:
这是跨平台的,可以在 Windows、Linux 和 macOS 上运行。它将 PowerShell 的范围扩展到 Windows 系统之外,使其在跨平台脚本和自动化方面更加通用。
.NET 版本...
PowerShell 5.1:
它依赖于 .NET Framework,这是一种仅限 Windows 的技术。它使用 .NET Framework 4.5。
PowerShell 7:
这是基于跨平台的 .NET Core(现在称为 .NET 5+)构建的。它受益于 .NET Core 的改进性能和跨平台兼容性。
与模块的兼容性...
PowerShell 5.1:
它支持各种特定于 Windows 的模块和 cmdlet。某些模块和 cmdlet 在跨平台方案中可能不起作用。
PowerShell 7:
虽然它保持与为 PowerShell 5.1 设计的许多模块的兼容性,但它也提供了新功能和改进。它与跨平台模块和 cmdlet 更兼容,使其适用于多平台脚本。
语言功能和改进...
PowerShell 5.1:
它具有该版本可用的功能和改进,但开发和增强主要集中在 Windows 上。
PowerShell 7:
它引入了新的语言功能和改进,以及错误修复。在保持向后兼容性的同时,它还增加了对现代脚本实践和跨平台功能的支持。
PowerShell 库...
PowerShell 5.1:
它使用 PowerShell 库主要为 Windows 环境分发模块和脚本。
PowerShell 7:
它继续使用 PowerShell 库,但提供了更广泛的模块和脚本,可以跨不同平台使用。
社区和开源...
PowerShell 5.1:
它由 Microsoft 开发和维护,遵循传统的闭源开发模型。
PowerShell 7:
它是托管在 GitHub 上的开源项目。社区积极为其发展做出贡献,并从更广泛的用户的投入和贡献中受益。
所以。。。PowerShell 5.1 是传统的以 Windows 为中心的版本,而 PowerShell 7 是跨平台的开源继任者,带来了许多改进和在多个操作系统上工作的能力。
我希望这会有所帮助。
评论
我发现了为什么它没有在 PS 5.1 中运行的问题。我用详细的例外更新了我的问题。DLL“System.Runtime.CompilerServices.Unsafe.dll”未在 PowerShell 会话中加载,导致脚本失败。在 PS 7 中,默认情况下会加载此 dll。我当时只有一个更新的版本,所以我需要在 PowerShell 5.1 中进行绑定重定向。我从这个问题中得到了做到这一点的方法:Powershell 配置程序集重定向
这是我在 PS 5.1 中工作的示例脚本
$CertPassWord = "password" # Password used for creating the certificate
$CertificatePath_Pfx = "C:\Temp\Certs\test.pfx" # Path where the certificate is saved
[System.Reflection.Assembly]::LoadFrom("C:\Temp\Certs\Microsoft.IdentityModel.Tokens.dll")
[System.Reflection.Assembly]::LoadFrom("C:\Temp\Certs\System.Runtime.CompilerServices.Unsafe.dll")
$OnAssemblyResolve = [System.ResolveEventHandler] {
param($sender, $e)
$searchFor = $null
if ($e.Name -match "(.*?), .*") {
$searchFor = $matches[1]
}
foreach ($a in [System.AppDomain]::CurrentDomain.GetAssemblies()) {
Write-Host $a
$foundItem = $null
if ($a.FullName -match "(.*?), .*") {
$foundItem = $matches[1]
}
if ($foundItem -eq $searchFor) {
return $a
}
}
return $null
}
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($OnAssemblyResolve)
try {
$x509cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2($CertificatePath_Pfx, $CertPassWord)
new-object Microsoft.IdentityModel.Tokens.X509SigningCredentials($x509cert)
}
catch {
Write-Host "An error occurred:"
Write-Host $_.Exception
}
评论
System.IdentityModel.Tokens.Jwt
是跨版本包。