Invoke-CimMethod执行后现有PSSession无法使用的问题求助
问题描述
两段代码单独运行均正常,但在同一脚本中执行时出现兼容性问题:
- 第一部分通过
Invoke-CimMethod成功启用目标主机的PSRemoting; - 第二部分原本可创建TEMP文件夹并复制目录,但在第一部分执行后,使用提前创建的
PSSession执行Copy-Item时出现错误:Copy-Item : The runspace state is not valid for this operation。
尝试执行Get-CimSession | Remove-CimSession无效,且该Invoke-CimMethod代码在其他类似脚本中可正常运行,需排查原因。
变量
$hostname = 'PC1' $Session = New-PSSession $hostname $DestinationPath = "C:\windows\temp"
第一部分(启用PSRemoting代码)
$SessionArgs = @{ ComputerName = $hostname Credential = $credential SessionOption = New-CimSessionOption -Protocol Dcom } $MethodArgs = @{ ClassName = 'Win32_Process' MethodName = 'Create' CimSession = New-CimSession @SessionArgs Arguments = @{ CommandLine = "powershell Start-Process powershell -ArgumentList 'Enable-PSRemoting -Force'" } } Invoke-CimMethod @MethodArgs
第二部分(文件夹创建与复制代码)
Invoke-Command -Session $Session -ScriptBlock { Param($Destination) New-Item -Path $Destination -ItemType Directory -ErrorAction SilentlyContinue} -ArgumentList $DestinationPath Copy-Item -Path "\\shared\folder\foo\bar" -ToSession $Session -Destination "C:\windows\temp\" -recurse -force
错误信息
Copy-Item : The runspace state is not valid for this operation.
可正常运行的示例
$env:hostname $env:process $SessionArgs = @{ ComputerName = $env:hostname Credential = $credential SessionOption = New-CimSessionOption -Protocol Dcom } $MethodArgs = @{ ClassName = 'Win32_Process' MethodName = 'Create' CimSession = New-CimSession @SessionArgs Arguments = @{ CommandLine = "powershell Start-Process powershell -ArgumentList 'Enable-PSRemoting -Force'" } } Invoke-CimMethod @MethodArgs $session = New-PSSession $env:hostname ipconfig Invoke-Command -Session $session -ScriptBlock {param($process) Stop-Process -ProcessName $process -Force} -ArgumentList $env:process $Session | Remove-PSSession
问题原因与解决方案
核心原因
脚本最开头就创建了$Session这个PSSession,但此时目标主机的PSRemoting还未启用(第一部分代码才执行启用操作),这个提前创建的Session从一开始就是无效状态。后续用这个失效的Session执行Copy-Item,自然会触发运行空间状态错误。
对比可正常运行的示例,其逻辑是先启用PSRemoting,再创建PSSession,执行顺序完全正确。
解决步骤
- 删除脚本开头提前创建的
$Session = New-PSSession $hostname代码; - 将
New-PSSession的创建逻辑移到第一部分启用PSRemoting之后,并且增加10-15秒的等待时间,确保PSRemoting服务完成配置并启动; - 提前清理可能存在的无效Session:
Get-PSSession -ComputerName $hostname | Remove-PSSession -ErrorAction SilentlyContinue。
修正后的完整脚本示例
$hostname = 'PC1' $DestinationPath = "C:\windows\temp" # 第一部分:启用PSRemoting $SessionArgs = @{ ComputerName = $hostname Credential = $credential SessionOption = New-CimSessionOption -Protocol Dcom } $MethodArgs = @{ ClassName = 'Win32_Process' MethodName = 'Create' CimSession = New-CimSession @SessionArgs Arguments = @{ CommandLine = "powershell Start-Process powershell -ArgumentList 'Enable-PSRemoting -Force'" } } Invoke-CimMethod @MethodArgs # 等待PSRemoting生效,时间可根据实际情况调整 Write-Host "等待PSRemoting服务启动..." Start-Sleep -Seconds 12 # 清理可能存在的无效Session,再创建新的有效Session Get-PSSession -ComputerName $hostname | Remove-PSSession -ErrorAction SilentlyContinue $Session = New-PSSession $hostname -Credential $credential # 第二部分:创建文件夹并复制内容 Invoke-Command -Session $Session -ScriptBlock { Param($Destination) New-Item -Path $Destination -ItemType Directory -ErrorAction SilentlyContinue } -ArgumentList $DestinationPath Copy-Item -Path "\\shared\folder\foo\bar" -ToSession $Session -Destination "C:\windows\temp\" -Recurse -Force # 清理Session $Session | Remove-PSSession
内容的提问来源于stack exchange,提问作者DrixlRey
相关产品推荐
相关产品推荐

