Powershell 使 RemoteDrive 会话保持打开状态
Powershell leaving RemoteDrive Sessions open
最小问题:
如何正确处理执行后留下的远程会话连接:
$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
}
我的目的是让一组远程机器全部调用一个 exe
坐在我的机器上,通过远程共享公开。
一般来说,我:
- 以我自己的身份连接到远程机器。
- 捕获该连接。
- 设置一个连接到我的远程驱动器
- (这是避免双跳问题而不诉诸
CredSsp
所必需的,请参阅:https://docs.microsoft.com/en-us/powershell/scripting/setup/ps-remoting-second-hop)
- 做一些事情
- 对所有机器重复。
- 等到远程进程完成。
- 重新连接到所有机器以删除驱动器和连接会话。
最后,我还有:
这些会话最终似乎会衰减,但并不可靠,并且它能够使允许的最大会话数达到饱和,从而导致错误提示:
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 的建议Get-SmbSession
。
运行 在我的脚本的其余部分之后 returns:
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 的建议):
$vmName = $env:ComputerName
$IP = [System.Net.Dns]::GetHostAddresses($vmName).IPAddressToString
Get-SmbSession | Where-Object {$_.ClientComputerName -eq $IP} | Close-SmbSession -Force
作为最终参考,我的完整清理代码如下所示:
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
}
最小问题:
如何正确处理执行后留下的远程会话连接:
$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
}
我的目的是让一组远程机器全部调用一个 exe
坐在我的机器上,通过远程共享公开。
一般来说,我:
- 以我自己的身份连接到远程机器。
- 捕获该连接。
- 设置一个连接到我的远程驱动器
- (这是避免双跳问题而不诉诸
CredSsp
所必需的,请参阅:https://docs.microsoft.com/en-us/powershell/scripting/setup/ps-remoting-second-hop)
- (这是避免双跳问题而不诉诸
- 做一些事情
- 对所有机器重复。
- 等到远程进程完成。
- 重新连接到所有机器以删除驱动器和连接会话。
最后,我还有:
这些会话最终似乎会衰减,但并不可靠,并且它能够使允许的最大会话数达到饱和,从而导致错误提示:
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 的建议Get-SmbSession
。
运行 在我的脚本的其余部分之后 returns:
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 的建议):
$vmName = $env:ComputerName
$IP = [System.Net.Dns]::GetHostAddresses($vmName).IPAddressToString
Get-SmbSession | Where-Object {$_.ClientComputerName -eq $IP} | Close-SmbSession -Force
作为最终参考,我的完整清理代码如下所示:
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
}