运行远程批处理文件时,Powershell进程“挂起”

4

我想通过驱动器映射的方式在远程服务器上运行批处理文件,但进程卡住了...

Enable-WSManCredSSP -Role Client -DelegateComputer someserver -Force

$credential = Get-Credential -Credential domain\user (then I supply the password in the popup)

$RemoteSession = New-PSSession -ComputerName someserver -Credential $credential -Authentication Credssp

Invoke-Command -Session $RemoteSession -ScriptBlock { Enable-WSManCredSSP -Role Server -Force }

Invoke-Command -Session $RemoteSession -ScriptBlock { New-PSDrive -Name I -PSProvider FileSystem -Root \\server\share$ }

到目前为止,一切都看起来很正常,我可以通过“dir”命令查看I驱动器并看到期望的内容。

但是当我执行以下操作时,进程会挂起 -

Invoke-Command -Session $RemoteSession -ScriptBlock { Start-Process I:\temp.bat }

temp.bat文件执行以下命令,我已经手动验证过它可以工作

echo Scott was here > C:\temp.txt

然而,该命令运行超过5分钟而没有任何响应。

有人可以帮忙吗?我做错了什么?


由于Start-Process不等待进程完成,我不认为它会等待。您是否尝试使用PowerShell命令替换批处理文件? - Lars Truijens
嗨Lars,我没有。我需要运行的实际文件是第三方批处理文件,所以我不确定有什么意义。最初我认为是这个文件出了问题,这就是为什么我将调用更改为重定向回显语句(如上所述)的原因。 - scottwilson_uk
Lars,你有没有看到过任何可以解释这个问题的东西?非常感谢您的帮助... - scottwilson_uk
可能与您的重定向有关。您可以尝试在批处理中删除> C:\temp.txt,并将-RedirectStandardOutput C:\temp.txt作为参数添加到Start-Process中。 - Anthony Neace
嗨,安东尼,我下周会试一下。唯一的问题是没有重定向,我不知道它是否有效!还有其他证明它有效的方法吗?谢谢。 - scottwilson_uk
您不必创建输出来查看命令是否有效。您可以使用$lastexitcode来实现此目的。您可以在以下线程中找到示例: https://dev59.com/QWoy5IYBdhLWcg3wcNrh - Paul
4个回答

0

虽然这不是你问题的直接解决方案,但是我从多周的头痛键盘中得出的建议是走另一条路。

$taskName = whocares
$command = I:\Temp.bat
$serverName = theServer
$userName = domain\user
$pass = pl4inT3xtPassword
$date = (Get-Date).addMinutes(1)
$formats = $date.getDateTimeFormats()
$startTime = $formats[113]
schtasks.exe /create /sc ONCE /tn $taskName /tr $command /s $serverName /u $userName /p $pass /ru $userName /rp $pass /st $startTime

这将创建一个任务,在下一分钟启动进程,然后从调度程序中删除自身。还有一个/z标志,用于在运行后删除,但如果你像我一样使用XP,则可能无法使用它。如果你注意到你的任务在运行后没有被删除,你可以等待一分钟然后杀掉它...或者你可以更加高级一些:

while(($timer -lt 60) -and (!$running)) {
    schtasks.exe /query /S $serverName /FO CSV /v /u $userName /p $pass | ConvertFrom-CSV | `
    % {if($_.Status -eq "Running") {
        Write-Host "IT WORKED!"
        Write-host $_
        $running = $true
      }
    }
    if(!$running) {
        $timer++
    }
    sleep 1
}
schtasks.exe /delete /s $serverName /u $userName /p $pass /tn $taskName /f

这段代码每秒钟查询一次任务是否在运行... 一旦它开始运行,它将删除旧的计划任务,您的进程将继续运行(直到完成)。

任务计划程序是我发现使用PowerShell远程启动进程的唯一干净方式。它不会成为PSremote.exe的子进程,而是在System下运行。此外,与远程会话不同,如果您关闭powershell会话,该进程将在远程计算机上持续存在。

我知道这不仅仅是一个简单的命令,但我希望它有用,如果您对其进行参数化或甚至在其上构建一个Windows窗体应用程序,它将为您节省大量时间和烦恼。

更多关于schtasks 请点击这里


0

尝试在您的Invoke-Command行末添加-AsJob参数?


0

感谢您的建议。

由于其他问题(与我们最终试图运行的过程有关),我们暂时把这个问题放下了,没有找到解决方案。

感谢您的帮助和建议。希望几周后能够重新开始解决。 Scott


0

提醒一下,如果 Invoke-Command 总是挂起,可能是由于服务或防火墙的原因:

  1. 尝试向系统发送一个简单的命令: Invoke-Command -ComputerName XXXXX -ScriptBlock { Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion }

  2. 启动 Windows 远程管理服务(在该系统上)

  3. 检查监听端口:

     netstat -aon | findstr "5985"
          TCP    0.0.0.0:5985           0.0.0.0:0              LISTENING       4
          TCP    [::]:5985              [::]:0                 LISTENING       4
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接