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:
CredSsp
See: https://learn.microsoft.com/en-us/powershell/scripting/setup/ps-remoting-second-hop)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?
To Close the SMB sessions by computer name(Updated to include Brondahl's suggestion):
$vmName = $env:ComputerName
$IP = [System.Net.Dns]::GetHostAddresses($vmName).IPAddressToString
Get-SmbSession | Where-Object {$_.ClientComputerName -eq $IP} | Close-SmbSession -Force