Powershell使RemoteDrive会话保持打开状态
最小问题: 执行以下操作后,如何正确处理留下的远程会话连接:Powershell使RemoteDrive会话保持打开状态,powershell,windows-share,Powershell,Windows Share,最小问题: 执行以下操作后,如何正确处理留下的远程会话连接: $session = New-PSSession -ComputerName $VM -Credential $CurrentUser Invoke-Command -Session $session -ScriptBlock { $drive = New-PSDrive -Credential $Using:CurrentUser "dummyDriveName" -Root (Split-Path $Using:Targe
$session = New-PSSession -ComputerName $VM -Credential $CurrentUser
Invoke-Command -Session $session -ScriptBlock {
$drive = New-PSDrive -Credential $Using:CurrentUser "dummyDriveName" -Root (Split-Path $Using:TargetPath) -PSProvider "FileSystem"
Set-Location $Using:TargetPath
}
Invoke-Command -Session $session -ScriptBlock {
Remove-PSDrive "dummyDriveName"
}
Remove-PSSession -Session $session
我运行的代码大致如下所示:
$VMs = @(
"vm1.foo.lan",
"vm2.foo.lan",
"vm3.foo.lan"
)
$TargetPath = "\\$env:ComputerName\bar\bin\Debug"
$CurrentUser = (Get-Credential -Credential $env:UserName)
[System.Management.Automation.Runspaces.PSSession[]]$Sessions = @()
foreach ($VM in $VMs) {
$session = New-PSSession -ComputerName $VM -Credential $CurrentUser
$Sessions = $Sessions + $session
Invoke-Command -Session $session -ScriptBlock {
$drive = New-PSDrive -Credential $Using:CurrentUser "dummyDriveName" -Root (Split-Path $Using:TargetPath) -PSProvider "FileSystem"
Set-Location $Using:TargetPath
#Actually do something here, but it's not relevant ... I can reproduce with this line commented out.
}
}
# Wait until Target.exe are known to be complete.
foreach ($session in $Sessions) {
Invoke-Command -Session $session -ScriptBlock {
Remove-PSDrive "dummyDriveName"
}
Remove-PSSession -Session $session
}
foreach ($session in $Sessions) {
Write-Host ""
$vmName = $session.ComputerName
$vmIPAddress = [System.Net.Dns]::GetHostAddresses($vmName).IPAddressToString
Write-Host "*** Killing any active Target.exe processes on $vmName ***"
Invoke-Command -Session $session -ScriptBlock {
Stop-Process -Name "Target" -Force
}
Write-Host "*** Disconnecting the remote Drive created to give $vmName easy access to $RepositoryShare***"
Invoke-Command -Session $session -ScriptBlock {
Remove-PSDrive "dummyDriveName"
}
Write-Host "*** Closing any open PS connections to $vmName ***"
Remove-PSSession -Session $session
Write-Host "*** Closing the still-open Windows Share connection from $vmName to $env.ComputerName ***"
Get-SmbSession | Where-Object {$_.ClientComputerName -eq $vmIPAddress} | Close-SmbSession -Force
}
我的目的是让一组远程机器都调用我机器上的exe
,通过远程共享公开
广义而言,我:
- 以我自己的身份连接到远程机器
- 捕捉这种联系
- 设置一个连接到我的远程驱动器
- (这是为了避免双跳问题而不诉诸于
请参见:)CredSsp
- (这是为了避免双跳问题而不诉诸于
- 做点什么
- 对所有机器重复上述步骤
- 等待远程进程完成
- 重新连接到所有机器以卸下驱动器和连接会话
No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept
+ CategoryInfo : InvalidOperation: (dummy:PSDriveInfo) [New-PSDrive], Win32Exception
+ FullyQualifiedErrorId : CouldNotMapNetworkDrive,Microsoft.PowerShell.Commands.NewPSDriveCommand
+ PSComputerName : build7.foo.lan
更新: 感谢@jrider,他建议
获取SmbSession
。
在脚本的其余部分返回后运行:
PS C:\WorkingDirectoty> Get-SmbSession
SessionId ClientComputerName ClientUserName NumOpens
--------- ------------------ -------------- --------
773228331225 10.xxx.yyy.89 FOO\MDM 785
773228331233 10.xxx.yyy.60 FOO\MDM 637
773228331245 10.xxx.yyy.89 FOO\MDM 239
773228331253 10.xxx.yyy.54 FOO\MDM 136
773228331261 10.xxx.yyy.54 FOO\MDM 882
773228331269 10.xxx.yyy.60 FOO\MDM 389
很明显,我不想让这个脚本盲目地关闭每个会话,不管它是否与这个脚本相关,所以我想我想把我的会话映射到IP地址,然后关闭任何有这个IP地址的会话?
有人知道实现这一点所需的PowerShell咒语吗?按计算机名关闭SMB会话(更新以包括Brondahl的建议):
作为最终参考,我的完整清理代码如下所示:
$VMs = @(
"vm1.foo.lan",
"vm2.foo.lan",
"vm3.foo.lan"
)
$TargetPath = "\\$env:ComputerName\bar\bin\Debug"
$CurrentUser = (Get-Credential -Credential $env:UserName)
[System.Management.Automation.Runspaces.PSSession[]]$Sessions = @()
foreach ($VM in $VMs) {
$session = New-PSSession -ComputerName $VM -Credential $CurrentUser
$Sessions = $Sessions + $session
Invoke-Command -Session $session -ScriptBlock {
$drive = New-PSDrive -Credential $Using:CurrentUser "dummyDriveName" -Root (Split-Path $Using:TargetPath) -PSProvider "FileSystem"
Set-Location $Using:TargetPath
#Actually do something here, but it's not relevant ... I can reproduce with this line commented out.
}
}
# Wait until Target.exe are known to be complete.
foreach ($session in $Sessions) {
Invoke-Command -Session $session -ScriptBlock {
Remove-PSDrive "dummyDriveName"
}
Remove-PSSession -Session $session
}
foreach ($session in $Sessions) {
Write-Host ""
$vmName = $session.ComputerName
$vmIPAddress = [System.Net.Dns]::GetHostAddresses($vmName).IPAddressToString
Write-Host "*** Killing any active Target.exe processes on $vmName ***"
Invoke-Command -Session $session -ScriptBlock {
Stop-Process -Name "Target" -Force
}
Write-Host "*** Disconnecting the remote Drive created to give $vmName easy access to $RepositoryShare***"
Invoke-Command -Session $session -ScriptBlock {
Remove-PSDrive "dummyDriveName"
}
Write-Host "*** Closing any open PS connections to $vmName ***"
Remove-PSSession -Session $session
Write-Host "*** Closing the still-open Windows Share connection from $vmName to $env.ComputerName ***"
Get-SmbSession | Where-Object {$_.ClientComputerName -eq $vmIPAddress} | Close-SmbSession -Force
}
您是否可以使用
Copy Item-ToSession
将exe复制到远程计算机并从那里运行(如有必要,随后删除)?无需重新连接等。对于您的问题,“我如何正确地处理完成后留下的远程会话连接…”您已经知道了Remove-PSSession
@lordam显然不是,因为这样做之后这些会话仍然存在@boxdog的想法不错,但不幸的是,由于目标的性质,它不是一个选项。exe@Brondahl在删除之前,您是否尝试过使用退出PSSession
?不知道这是否会造成不同您是否可以添加[System.Net.Dns]::GetHostAddresses($vmName).IPAddressToString
来获取整个内容(来源:)