Búsqueda de sitios web

Obtenga conexiones de sesión remota de PowerShell


#requires -version 3.0

Function Get-PSRemoteSession {

<#
.SYNOPSIS
Get remote PSSession processes.
.DESCRIPTION
This command uses CIM to retrieve the wsmprovhost process that might be running
on a remote computer. You can use this information to determine how long a 
session has been running and by what user. By default the command shows a 
summary. If you want to see the full detail, use the -Full parameter. The
process owner and runtime will be added to the object in either case.
.PARAMETER Computername
This parameter has aliases of CN, Name and PSComputername
.PARAMETER Full
Write the full process object to the pipeline instead of the summary.
.EXAMPLE
PS C:\> Get-PSRemoteSession lon-dc1

ProcessID      : 7016
CreationDate   : 4/3/2014 1:25:32 PM
Runtime        : 23:36:38.0799372
Owner          : MYDOMAIN\Jeff
PSComputername : lon-dc1

ProcessID      : 4676
CreationDate   : 4/4/2014 12:23:41 PM
Runtime        : 00:38:28.9568735
Owner          : MYDOMAIN\Administrator
PSComputername : lon-dc1

.EXAMPLE
PS C:\> Get-PSRemoteSession lon-dc1 -full | select Owner,ProcessID,VM,WS,runtime

Owner     : MYDOMAIN\Jeff
ProcessID : 7016
VM        : 163262464
WS        : 44392448
Runtime   : 23:47:39.0140240

Owner     : MYDOMAIN\Administrator
ProcessID : 4676
VM        : 180445184
WS        : 46551040
Runtime   : 00:49:29.8899602

Get full process information and select some key properties
.EXAMPLE
PS C:\> get-remotesession chi-dc04,chi-dc01 | Group Owner -NoElement

Count Name                     
----- ----                     
    1 GLOBOMANTICS\jeff        
    2 GLOBOMANTICS\Administr...


Display what user accounts are using remote sessions on the specified computers.

.EXAMPLE
PS C:\> Get-Content c:\work\computers.txt | Get-PSRemoteSession | where {$_.Runtime -gt "16:00:00"}

For a list of computers, get remote PSSessions that have been running longer 
than 16 hours.

.EXAMPLE
PS C:\> get-remotesession chi-dc04,chi-dc01,chi-app01 | sort PSComputername | format-table -GroupBy PSComputername -Property CreationDate,Runtime,Owner


   PSComputerName: chi-app01

CreationDate                 Runtime                     Owner                      
------------                 -------                     -----                      
4/11/2014 9:58:16 AM         00:04:29.8719959            GLOBOMANTICS\Administrator 


   PSComputerName: chi-dc01

CreationDate                 Runtime                     Owner                      
------------                 -------                     -----                      
4/11/2014 9:46:24 AM         00:16:21.2699348            GLOBOMANTICS\Administrator 


   PSComputerName: chi-dc04

CreationDate                 Runtime                     Owner                      
------------                 -------                     -----                      
4/11/2014 9:43:06 AM         00:19:36.8797428            GLOBOMANTICS\jeff          
4/11/2014 9:47:25 AM         00:15:18.0563043            GLOBOMANTICS\Administrator 

.NOTES
Version       : 1.0
Last Updated  : April 11, 2014

Learn more:
 PowerShell in Depth: An Administrator's Guide (http://www.manning.com/jones2/)
 PowerShell Deep Dives (http://manning.com/hicks/)
 Learn PowerShell 3 in a Month of Lunches (http://manning.com/jones3/)
 Learn PowerShell Toolmaking in a Month of Lunches (http://manning.com/jones4/)
 

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************
.LINK
Get-CimInstance
about_PSSessions
#>

[cmdletbinding()]
Param(
[Parameter(Position=0,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True)]
[ValidateNotNullorEmpty()]
[Alias("CN","Name","PSComputername")]
[string[]]$Computername,
[switch]$Full
)

Begin {
    Write-Verbose "Starting Get-PSRemoteSession"
} #begin

Process {
foreach ($computer in $computername) {
    #test connection
    Write-Verbose "Testing if computer $computer is pingable"

    #do a single ping to verify computer is up
    If (Test-Connection -ComputerName $computer -count 1 -Quiet) {

        Write-Verbose "Querying $computer"
        Try {
            #use CIM to remotely query the computer
            $data = Get-CimInstance win32_process -filter "name='wsmprovhost.exe'" `
            -ComputerName $computer -ErrorAction Stop -ErrorVariable MyErr

            if ($data) {
                Write-verbose "Found sessions on $computer"
                Write-verbose ($data[0] | out-string)

                #add some custom properties
                $data | Add-Member -membertype ScriptProperty -Name Runtime -value {
                (Get-Date) - $this.creationdate} 
                $data | Add-Member -MemberType ScriptProperty -Name Owner -Value {
                $owner = $this | Invoke-CimMethod -MethodName GetOwner
                #write the owner information
                "$($owner.domain)\$($owner.user)"
                } 
                
                if ($Full) {
                    #write the full process object with additions to the pipeline
                    $data
                }
                else {
                    #get process summary
                    $data | Select ProcessID,CreationDate,RunTime,Owner,PSComputername  
                  }    

            } #if $data

         } #try

         Catch {
           Write-Warning "Could not query $computer"
           Write-Warning $myErr.ErrorRecord.Exception.Message
           Write-Debug "Suspend script to debug `$myErr exception"
         } #catch

     } #if test-connection works
     else {
       Write-Warning "Failed to ping $computer"
     }

} #foreach computer
} #process

End {
 Write-verbose "Ending Get-PSRemoteSession"
} #end

} #end function

Esta función toma un nombre de computadora como parámetro. Hace un ping rápido para verificar que la computadora esté funcionando. Probablemente debería haberlo hecho opcional, pero lo necesitaba en ese momento. Luego, la función consulta la computadora usando Get-CimInstance para todas las instancias del proceso wsmprovhost.exe. Estoy usando CIM porque los valores de fecha y hora se formatean automáticamente, lo que hace que sea mucho más fácil agregar una propiedad personalizada que indique cuánto tiempo se ha estado ejecutando el proceso y, presumiblemente, la sesión remota. También agrego una propiedad personalizada para obtener el propietario del proceso. Debido a una peculiaridad (¿error?) en los cmdlets de CIM, incluso puedo consultar una computadora remota que ejecuta PowerShell 2.0. Cuando se utiliza un filtro, los cmdlets CIM funcionan con una computadora v2. No lo cuestionaré pero lo aprovecharé.

De forma predeterminada, la función escribe un objeto de resumen en la canalización.

Lo único que todavía tengo que descubrir es una manera de mostrar desde qué computadora está conectada cada sesión. Aunque incluso si pudiera hacer la correlación con una conexión de red activa, no estoy seguro de que eso ayudaría en caso de una sesión desconectada. Tampoco puedo distinguir el estado de la sesión del proceso.

Incluí una opción para obtener el objeto de proceso completo para que pudieras ejecutar comandos como este:

Pero sospecho que para muchos de ustedes el resumen será suficiente. Aquí hay unos ejemplos.

Get-Content c:\work\chi.txt | get-psremotesession | out-gridview -title "Remote Sessions"

Si mata el proceso wsmprovhost, se interrumpirá la PSSession, así que tenga cuidado. Pero al menos ahora tienes una forma de identificar qué sesiones podrían estar abiertas. Espero que me dejes saber lo que piensas. ¡Disfrutar!

Artículos relacionados