在PowerShell WorkFlow中使用Posh-SSH的Set-SFTPFile报空引用错误如何解决
问题根因
该错误和POSH-SSH版本无关,是PowerShell Workflow的固有机制导致的:Workflow的每个并发活动都会运行在独立的PowerShell运行空间中,POSH-SSH模块的全局会话缓存不会在多个运行空间之间共享,你在Workflow外部或者其他活动中创建的SFTP会话,在执行Set-SFTPFile的运行空间中不存在,所以即使拿到了SessionId也找不到对应的会话实例,才会抛出空引用错误。
可行解决方案
方案1:将SFTP操作全链路放到InlineScript块中(最稳妥,适配所有版本)
在Workflow的并发逻辑中,不要跨代码块传递SFTP会话ID,所有SFTP的连接、传文件、销毁操作都放在同一个InlineScript内部执行,每个并发任务单独维护自己的会话,示例代码:
workflow StartExport { # 你的其他Workflow逻辑 ForEach -Parallel ($file in $files) { InlineScript { # 导入POSH-SSH模块 Import-Module Posh-SSH -RequiredVersion 2.3.0 # 内部单独创建SFTP会话 $sftpSession = New-SFTPSession -ComputerName "你的SFTP地址" -Credential $using:sftpCred # 执行文件传输 $localPath = "$using:encrypted\$($using:file.Name).pgp" Set-SFTPFile -SessionId $sftpSession.SessionId -LocalFile $localPath -RemotePath ".\path" # 销毁当前会话 Remove-SFTPSession -SessionId $sftpSession.SessionId } } }
方案2:替换为系统内置OpenSSH命令行工具(无额外依赖,不影响现有业务)
如果服务器已经预装了OpenSSH客户端(Windows Server 2019/Windows 10及以上版本默认自带,无需额外安装),可以直接调用系统sftp命令传文件,完全绕开POSH-SSH模块的兼容性问题,示例命令:
# 密钥认证方式 sftp -i C:\路径\你的私钥.pem 用户名@SFTP地址:"/远程路径/目标文件名.pgp" "$encrypted\$($file.Name).pgp" # 密码认证可以配合psftp工具,或者使用PowerShell传递密码输入
这个方案不需要升级.NET、不需要改动POSH-SSH版本,不会影响服务器上的其他自动化任务。
方案3:弃用PowerShell Workflow,改用PowerShell作业实现并发
PowerShell Workflow已经是被微软标记为过时的功能,后续版本不再维护,如果你可以调整并发实现方式,改用Start-Job/Start-ThreadJob线程作业或者后台作业实现并发,POSH-SSH的原有调用逻辑完全不需要修改,也不会出现运行空间隔离导致的空引用问题。
内容的提问来源于stack exchange,提问作者alexander7567
相关产品推荐
相关产品推荐

