PowerShell Core中如何接入PowerShell 5.1会话?
问题场景
脚本依赖PowerShell Core,但需使用微软不再为Core更新的旧模块(ActiveDirectory/GroupPolicy)。尝试Import-Module -UseWindowsPowerShell时,因序列化问题无法获取所需的大部分信息;尝试在Core下注册PowerShell 5.1会话配置时,收到错误:
Cannot bind parameter 'PSVersion' to the target. Exception setting "PSVersion": "PowerShell remoting endpoint versioning is not supported on PowerShell Core.
临时方案为调用powershell.exe执行代码并解析输出,但易出现格式问题,需更可靠的解决方法。
尝试过的失败操作
在PowerShell Core中执行以下注册会话配置的代码:
$registerPSSessionConfigurationSplat = @{ "RunAsPassword" = "" "ResourceUri" = "http://schemas.microsoft.com/powershell/microsoft.powershell" "Capability" = @("Shell") "PSVersion" = "5.1" "AutoRestart" = $false "ExactMatch" = $true "RunAsVirtualAccount" = $false "SDKVersion" = "2" "Uri" = "http://schemas.microsoft.com/powershell/microsoft.powershell" "MaxConcurrentCommandsPerShell" = "2147483647" "IdleTimeoutms" = "7200000" "ParentResourceUri" = "http://schemas.microsoft.com/powershell/microsoft.powershell" "RunAsUser" = "" "OutputBufferingMode" = "Block" "Architecture" = "64" "MaxMemoryPerShellMB" = "2147483647" "MaxProcessesPerShell" = "2147483647" "Filename" = "%windir%\\system32\\pwrshplugin.dll" "MaxShellsPerUser" = "2147483647" "MaxShells" = "2147483647" "SupportsOptions" = $true "lang" = "de-DE" "MaxIdleTimeoutms" = "2147483647" "xmlns" = "http://schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration" "Enabled" = $true "SecurityDescriptorSddl" = "O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;IU)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)" "Name" = "Powershell.5.1" "ProcessIdleTimeoutSec" = "0" "MaxConcurrentUsers" = "2147483647" "UseSharedProcess" = $false "RunAsVirtualAccountGroups" = "" "XmlRenderingType" = "text" "Permission" = "NT-AUTORITÄT\\INTERAKTIV AccessAllowed", "VORDEFINIERT\\Administratoren AccessAllowed", "VORDEFINIERT\\Remoteverwaltungsbenutzer AccessAllowed" } Register-PSSessionConfiguration @registerPSSessionConfigurationSplat
可行解决方案
1. 直接连接本地PowerShell 5.1默认远程会话
Windows系统默认已存在PowerShell 5.1的远程会话配置(Microsoft.PowerShell),无需在Core中重新注册,直接通过Invoke-Command或Enter-PSSession调用:
# 示例:在Core中调用5.1会话执行AD模块命令 $adUsers = Invoke-Command -ComputerName localhost -ConfigurationName Microsoft.PowerShell -ScriptBlock { Import-Module ActiveDirectory Get-ADUser -Filter {Enabled -eq $true} -Properties DisplayName, EmailAddress }
此方法返回的序列化对象可正常读取属性,若无需调用对象方法,完全满足需求。
2. 使用PowerShell作业指定5.1引擎运行
利用PowerShell作业系统,直接指定使用5.1版本引擎执行代码,无需远程配置:
# 启动5.1版本的作业执行组策略命令 $gpoJob = Start-Job -ScriptBlock { Import-Module GroupPolicy Get-GPO -All | Select-Object DisplayName, GpoStatus, CreationTime } -PSVersion 5.1 # 获取作业结果并清理作业 $gpoResults = Receive-Job $gpoJob -Wait -AutoRemoveJob
作业运行在独立的5.1进程中,结果处理比直接调用powershell.exe更规范。
3. 优化powershell.exe调用(备选方案)
若上述方法仍无法满足需求,可通过JSON序列化优化powershell.exe的输出,避免格式解析问题:
# 定义要在5.1中执行的代码块 $targetScript = { Import-Module ActiveDirectory Get-ADComputer -Filter * -Properties OperatingSystem, LastLogonDate } # 调用powershell.exe并以JSON格式输出,再在Core中反序列化 $jsonOutput = powershell.exe -NoProfile -Command "$targetScript | ConvertTo-Json -Depth 10" $computers = $jsonOutput | ConvertFrom-Json
指定足够的-Depth参数确保属性完整序列化,同时使用-NoProfile避免加载不必要的配置,提升稳定性。
内容的提问来源于stack exchange,提问作者Lars Grünheid

