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 坐在我的机器上,通过远程共享公开。

一般来说,我:

最后,我还有:

这些会话最终似乎会衰减,但并不可靠,并且它能够使允许的最大会话数达到饱和,从而导致错误提示:

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
}