Powershell оставляет открытыми сеансы RemoteDrive - PullRequest
0 голосов
/ 26 апреля 2018

Минимальный вопрос:

Как правильно избавиться от удаленного сеанса, оставленного после выполнения:

$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, сидящий на моей машине, через удаленный общий ресурс.

Вообще говоря, я:

  • Подключайтесь к удаленной машине как я.
  • Перехватите это соединение.
  • Настройте удаленный диск, подключив его ко мне
  • Делай что-нибудь
  • Повторите для всех машин.
  • Дождаться завершения удаленных процессов.
  • Повторно подключитесь ко всем машинам, чтобы извлечь диск и сеанс подключения.

В конце этого у меня все еще есть: enter image description here

Эти сеансы в конечном итоге, кажется, затухают, но ненадежно, и он смог насытить максимально допустимое количество # сеансов и, таким образом, вызвать ошибки, говоря:

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:

Спасибо @jrider, который предложил Get-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 нужно для этого?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Для окончательной справки мой полный код очистки выглядит так:

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
}
0 голосов
/ 26 апреля 2018

Чтобы закрыть сеансы SMB по имени компьютера (обновлено, чтобы включить предложение Брондал):

$vmName = $env:ComputerName
$IP =  [System.Net.Dns]::GetHostAddresses($vmName).IPAddressToString
Get-SmbSession | Where-Object {$_.ClientComputerName -eq $IP} | Close-SmbSession -Force
...