Minimal Question:
How do I properly dispose of the remote Session Connection left behind after doing:
$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
I'm running code that looks roughly like this:
$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
}
My intent is to get a set of remote machines to all invoke an exe
sitting on my machine, exposed via a remote share.
Broadly speaking, I:
- Connect to the remote machine as myself.
- Capture that connection.
- Set up a remote drive connecting it to me
- (This is REQUIRED to avoid the double hop issue without resorting to
CredSsp
See: https://learn.microsoft.com/en-us/powershell/scripting/setup/ps-remoting-second-hop)
- (This is REQUIRED to avoid the double hop issue without resorting to
- Do some stuff
- Repeat for all machines.
- Wait until remote processes are completed.
- Reconnect to all the machines to remove the drive and the connection session.
At the end of this, I still have:
These sessions do eventually seem to decay, but not reliably, and it's been able to saturate the max # sessions allowed and thus cause errors saying:
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
UPDATE:
Thanks to @jrider who has suggested Get-SmbSession
.
Running that after the rest of my script 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
I obviously don't want this script to blindly close EVERY session irrespective of whether it relates to this script, so I guess I want to map my sessions to IP addresses and close anything with that IP address? Does anyone JustKnow the necessary PowerShell incantation to achieve that?