VB.NET托管PowerShell无法运行模块Cmdlet问题求助
问题描述
- 原环境:Win10 + VB.NET 2015 Ent,依赖
System.Management.Automation.Runspaces,可正常运行PnP.PowerShell命令实现OneDrive文件上传 - 新环境:Win11,替换依赖为
Microsoft.PowerShell.5.ReferenceAssemblies,Windows PowerShell版本5.1,仅PowerShell原生命令可执行,PnP.PowerShell v1.9.0的Cmdlet无法运行 - 核心错误:
- 直接执行
Connect-PnPOnline时,抛出CommandNotFoundException:模块找到但无法加载;添加Import-Module后出现AuthorizationManager check failed(格式文件验证异常) - 改用
PowerShell.Create()方式时,无捕获错误但HadErrors为True,InvocationStateInfo.Reason为空
- 直接执行
- 本地PS ISE中相同脚本可正常运行
解决方案
1. 调整PowerShell执行策略
Win11默认执行策略更严格,可通过代码或系统设置放宽:
- 代码内配置Runspace执行策略:
Dim iss As InitialSessionState = InitialSessionState.CreateDefault() iss.ExecutionPolicy = ExecutionPolicy.RemoteSigned ' 或根据安全需求用Unrestricted Dim runspace As Runspace = RunspaceFactory.CreateRunspace(iss) runspace.Open()
- 系统级设置:以管理员身份运行PowerShell,执行
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser,确认允许执行本地脚本
2. 修复模块文件的互联网标记
AuthorizationManager check failed通常是因为模块文件被标记为来自外部,需解除锁定:
- 手动操作:右键
C:\Program Files\WindowsPowerShell\Modules\PnP.PowerShell\1.9.0\PnP.PowerShell.Format.ps1xml→ 属性 → 勾选「解除锁定」 - 命令行批量处理:
Get-ChildItem "C:\Program Files\WindowsPowerShell\Modules\PnP.PowerShell\1.9.0\*.ps1xml" | Unblock-File
3. 显式指定模块路径导入
避免模块加载时的路径歧义,在代码中添加完整路径的导入命令:
pipeline.Commands.AddScript("Import-Module 'C:\Program Files\WindowsPowerShell\Modules\PnP.PowerShell\1.9.0\PnP.PowerShell.psd1' -Force -ErrorAction Stop")
同时确保VB.NET应用以管理员身份运行,保证模块文件的访问权限
4. 改进PowerShell.Create()的错误捕获
此方式需主动读取错误流获取具体原因:
Dim ps As PowerShell = PowerShell.Create() ps.AddScript($"Connect-PnPOnline -Url '{webUrl}' -ClientId '{cid}' -ClientSecret '{cs}' -WarningAction Ignore") ps.AddScript("Get-PnPContext") ps.AddScript($"$RelativeURL = '{libNameTemp}'") ps.AddScript($"$CSVFile = '{filePath}'") ps.AddScript("$FolderObject = Get-PnPFolder -Url $RelativeURL") ps.AddScript("$Upload = Add-PnPFile -Path $CSVFile -Folder $FolderObject") Dim results As Collection(Of PSObject) = ps.Invoke() ' 读取详细错误信息 If ps.HadErrors Then For Each err In ps.Streams.Error ' 输出或记录错误内容 Console.WriteLine(err.ToString()) Next End If
5. 强制指定模块搜索路径
确保Runspace的模块路径包含PnP.PowerShell所在目录:
Dim iss As InitialSessionState = InitialSessionState.CreateDefault() iss.EnvironmentVariables("PSModulePath") = $"{iss.EnvironmentVariables("PSModulePath")};C:\Program Files\WindowsPowerShell\Modules" Dim runspace As Runspace = RunspaceFactory.CreateRunspace(iss) runspace.Open()
6. 替代方案:使用PnP Core SDK
若PowerShell调用始终存在兼容性问题,可直接使用原生.NET库PnP Core SDK(NuGet包:PnP.Core),无需依赖PowerShell模块:
' 需先安装PnP.Core和PnP.Core.Auth NuGet包 Imports PnP.Core Imports PnP.Core.Auth ' 上传文件示例 Using context As PnPContext = Await PnPContextFactory.CreateAsync(New AuthenticationProviderOptions() With { .ClientId = cid, .ClientSecret = cs, .SiteUrl = New Uri(webUrl) }) Using fileStream As FileStream = File.OpenRead(filePath) Await context.Web.GetFolderByServerRelativeUrl(libNameTemp).Files.AddAsync(Path.GetFileName(filePath), fileStream, True) End Using End Using
内容的提问来源于stack exchange,提问作者Oscar Marquez
相关产品推荐
相关产品推荐

