Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell使RemoteDrive会话保持打开状态_Powershell_Windows Share - Fatal编程技术网

Powershell使RemoteDrive会话保持打开状态

Powershell使RemoteDrive会话保持打开状态,powershell,windows-share,Powershell,Windows Share,最小问题: 执行以下操作后,如何正确处理留下的远程会话连接: $session = New-PSSession -ComputerName $VM -Credential $CurrentUser Invoke-Command -Session $session -ScriptBlock { $drive = New-PSDrive -Credential $Using:CurrentUser "dummyDriveName" -Root (Split-Path $Using:Targe

最小问题:

执行以下操作后,如何正确处理留下的远程会话连接:

$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
}
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
}
我的目的是让一组远程机器都调用我机器上的
exe
,通过远程共享公开

广义而言,我:

  • 以我自己的身份连接到远程机器
  • 捕捉这种联系
  • 设置一个连接到我的远程驱动器
    • (这是为了避免双跳问题而不诉诸于
      CredSsp
      请参见:)
  • 做点什么
  • 对所有机器重复上述步骤
  • 等待远程进程完成
  • 重新连接到所有机器以卸下驱动器和连接会话
在此结束时,我仍然有:

这些会话最终似乎会衰减,但不可靠,并且会使允许的最大会话饱和,从而导致错误,如:

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,他建议
获取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咒语吗?

按计算机名关闭SMB会话(更新以包括Brondahl的建议):


作为最终参考,我的完整清理代码如下所示:

$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
}
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
}

您是否可以使用
Copy Item-ToSession
将exe复制到远程计算机并从那里运行(如有必要,随后删除)?无需重新连接等。对于您的问题,“我如何正确地处理完成后留下的远程会话连接…”您已经知道了
Remove-PSSession
@lordam显然不是,因为这样做之后这些会话仍然存在@boxdog的想法不错,但不幸的是,由于目标的性质,它不是一个选项。exe@Brondahl在删除之前,您是否尝试过使用
退出PSSession
?不知道这是否会造成不同您是否可以添加
[System.Net.Dns]::GetHostAddresses($vmName).IPAddressToString
来获取整个内容(来源:)